From 2569bbcf330ae68cd3d26f57817090fff41739cf Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <quaritsch@ivt.tugraz.at> Date: Tue, 24 Jan 2023 17:50:04 +0100 Subject: [PATCH] implementation of realworld usage factors (ovc range calculation) implementation of weighted result (OVC + non-OVC run), extending/refactoring vehicle operation lookup tables implementation of summary calculation (ovc and non-OVC) --- VectoCommon/VectoCommon/Utils/SI.cs | 5 +- ...clarationModeCompletedBusRunDataFactory.cs | 2 + ...DeclarationModeHeavyLorryRunDataFactory.cs | 1 + ...DeclarationModePrimaryBusRunDataFactory.cs | 2 + ...arationModeSingleBusVectoRunDataFactory.cs | 1 + .../Models/Declaration/DeclarationData.cs | 166 +++++++++++++----- .../VehicleOperation/MileageLookup.cs | 17 +- .../VehicleOperation/RealWorldUsageFactors.cs | 42 +++++ .../StationaryChargingLookup.cs | 40 ++++- .../VehicleOperationLookup.cs | 35 ++-- .../Models/Simulation/Data/VectoRunData.cs | 8 +- .../VectoCore/OutputData/DeclarationReport.cs | 5 +- .../VectoCore/OutputData/OvcResultEntry.cs | 14 +- .../OutputData/XML/XMLDeclarationReport.cs | 1 + .../RealWorldUsageFactors.csv | 24 +++ VectoCore/VectoCore/VectoCore.csproj | 1 + .../Models/Declaration/DeclarationDataTest.cs | 31 ++-- 17 files changed, 284 insertions(+), 111 deletions(-) create mode 100644 VectoCore/VectoCore/Models/Declaration/VehicleOperation/RealWorldUsageFactors.cs create mode 100644 VectoCore/VectoCore/Resources/Declaration/VehicleOperation/RealWorldUsageFactors.csv diff --git a/VectoCommon/VectoCommon/Utils/SI.cs b/VectoCommon/VectoCommon/Utils/SI.cs index 41888952c4..ba63be5497 100644 --- a/VectoCommon/VectoCommon/Utils/SI.cs +++ b/VectoCommon/VectoCommon/Utils/SI.cs @@ -665,7 +665,10 @@ namespace TUGraz.VectoCommon.Utils return SIBase<WattSecondPerMeter>.Create(wattSecond.Val / m.Value()); } - + public static Meter operator /(WattSecond wattSecond, WattSecondPerMeter m) + { + return SIBase<Meter>.Create(wattSecond.Val / m.Value()); + } } public class WattSecondPerMeter : SIBase<WattSecondPerMeter> diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/CompletedBusRunDataFactory/DeclarationModeCompletedBusRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/CompletedBusRunDataFactory/DeclarationModeCompletedBusRunDataFactory.cs index 5c24dea35e..4533cb82e5 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/CompletedBusRunDataFactory/DeclarationModeCompletedBusRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/CompletedBusRunDataFactory/DeclarationModeCompletedBusRunDataFactory.cs @@ -122,6 +122,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl.DeclarationMode.CompletedBusRun InputDataHash = DataProvider.MultistageJobInputData.XMLHash, SimulationType = SimulationType.DistanceCycle, VehicleDesignSpeed = _segmentCompletedBus.DesignSpeed, + MaxChargingPower = PrimaryVehicle.MaxChargingPower, //GearshiftParameters = _gearshiftData, }; simulationRunData.EngineData.FuelMode = 0; @@ -170,6 +171,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl.DeclarationMode.CompletedBusRun InputDataHash = DataProvider.MultistageJobInputData.XMLHash,// right hash?!? SimulationType = SimulationType.DistanceCycle, VehicleDesignSpeed = _segmentCompletedBus.DesignSpeed, + MaxChargingPower = PrimaryVehicle.MaxChargingPower, //GearshiftParameters = _gearshiftData, }; simulationRunData.EngineData.FuelMode = 0; diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/HeavyLorryRunDataFactory/DeclarationModeHeavyLorryRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/HeavyLorryRunDataFactory/DeclarationModeHeavyLorryRunDataFactory.cs index a7a9601956..85eb40a70d 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/HeavyLorryRunDataFactory/DeclarationModeHeavyLorryRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/HeavyLorryRunDataFactory/DeclarationModeHeavyLorryRunDataFactory.cs @@ -92,6 +92,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl.DeclarationMode.HeavyLorryRunDa ModFileSuffix = (engineModes?.Count > 1 ? $"_EngineMode{modeIdx}_" : "") + loading.Key, VehicleDesignSpeed = segment.DesignSpeed, InputDataHash = InputDataProvider.XMLHash, + MaxChargingPower = InputDataProvider.JobInputData.Vehicle.MaxChargingPower, }; return simulationRunData; } diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/PrimaryBusRunDataFactory/DeclarationModePrimaryBusRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/PrimaryBusRunDataFactory/DeclarationModePrimaryBusRunDataFactory.cs index e4785da69b..cc8b24125a 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/PrimaryBusRunDataFactory/DeclarationModePrimaryBusRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/PrimaryBusRunDataFactory/DeclarationModePrimaryBusRunDataFactory.cs @@ -139,6 +139,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl.DeclarationMode.PrimaryBusRunDa null, new KeyValuePair<LoadingType, Tuple<Kilogram, double?>>(LoadingType.ReferenceLoad, Tuple.Create<Kilogram, double?>(0.SI<Kilogram>(), null)), _allowVocational), + //MaxChargingPower = InputDataProvider.JobInputData.Vehicle.MaxChargingPower, InputDataHash = InputDataProvider.XMLHash }; } @@ -179,6 +180,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl.DeclarationMode.PrimaryBusRunDa SimulationType = SimulationType.DistanceCycle, GearshiftParameters = _gearshiftData, JobType = vehicle.VehicleType, + MaxChargingPower = vehicle.MaxChargingPower, }; simulationRunData.EngineData.FuelMode = modeIdx.Value; simulationRunData.VehicleData.VehicleClass = _segment.VehicleClass; diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/SingleBus/DeclarationModeSingleBusVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/SingleBus/DeclarationModeSingleBusVectoRunDataFactory.cs index 5f22660d9a..6035a37256 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/SingleBus/DeclarationModeSingleBusVectoRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationMode/SingleBus/DeclarationModeSingleBusVectoRunDataFactory.cs @@ -210,6 +210,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl.DeclarationMode.SingleBus SimulationType = SimulationType.DistanceCycle, GearshiftParameters = _gearshiftData, VehicleDesignSpeed = _segment.DesignSpeed, + MaxChargingPower = primaryVehicle.MaxChargingPower, //ShiftStrategy = InputDataProvider.JobInputData.ShiftStrategy }; simulationRunData.EngineData.FuelMode = modeIdx; diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs index 3e387569c4..db1ad76314 100644 --- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs @@ -1391,65 +1391,143 @@ namespace TUGraz.VectoCore.Models.Declaration if (cdResult.Status != VectoRun.Status.Success || csResult.Status != VectoRun.Status.Success) { return null; } - // ToDo MQ 2022-12-12: add correct calculation method! - return new WeightedResult(cdResult) { + var vehicleOperation = VehicleOperation.LookupVehicleOperation(cdResult.VehicleClass, cdResult.Mission); + + var D9_dailySpecificMileage = vehicleOperation.Mileage.DailyMileage; + var D10_stationarychargingDuringMissionMaxPwrInfastructure = vehicleOperation.StationaryChargingMaxPwrInfrastructure; + var D11_stationaryChargingDuringMission_AvgDurationPerEvent = vehicleOperation.StationaryChargingDuringMission_AvgDurationPerEvent; + var D12_stationaryChargingDuringMission_NbrEvents = vehicleOperation.StationaryChargingDuringMission_NbrEvents; + var D13_realWorldFactorUsageStartSoC = vehicleOperation.RealWorldUsageFactors.StartSoCBeforeMission; + var D14_realWorldFactorChargeDuringMission = vehicleOperation.RealWorldUsageFactors.StationaryChargingDuringMission; + + var D15_chargingEffBatt = 0.975; // TODO!! + var D16_ = 1.0; + var D18_maxStatChargingPower = cdResult.MaxChargingPower; + + var D19_useableBatteryCapacity = 0.SI<WattSecond>(); // TODO! + var D20_energyConsumptionCdMode = cdResult.ElectricEnergyConsumption / cdResult.Distance; + var D21_fuelConsumptionCdMode = cdResult.FuelData.Sum(x => cdResult.FuelConsumptionFinal(x.FuelType).TotalFuelConsumptionCorrected * x.LowerHeatingValueVecto); + var D22_fuelConsumptionCsMode = csResult.FuelData.Sum(x => csResult.FuelConsumptionFinal(x.FuelType).TotalFuelConsumptionCorrected * x.LowerHeatingValueVecto); + + var D24_useableBatteryCapForR_CDA = D19_useableBatteryCapacity * D16_; + var D25_actualChargeDepletingRange = D24_useableBatteryCapForR_CDA / D20_energyConsumptionCdMode; + + var D29_elRangefromStartSoC_ChargingAtDepot = D25_actualChargeDepletingRange * D13_realWorldFactorUsageStartSoC; + var D30_electricEnergyChargedDuringMissionStatInfrastructure = + VectoMath.Min( + VectoMath.Min(D18_maxStatChargingPower, D10_stationarychargingDuringMissionMaxPwrInfastructure) * + D11_stationaryChargingDuringMission_AvgDurationPerEvent * D15_chargingEffBatt, + D24_useableBatteryCapForR_CDA) * D12_stationaryChargingDuringMission_NbrEvents * D14_realWorldFactorChargeDuringMission; + var D31_elRangeStatChargingDuringMission = D30_electricEnergyChargedDuringMissionStatInfrastructure / D20_energyConsumptionCdMode; + + var D33_utilityFactor = Math.Min(1, (D29_elRangefromStartSoC_ChargingAtDepot + D31_elRangeStatChargingDuringMission) / D9_dailySpecificMileage); + + var D26_equivalentAllElectricRange = D25_actualChargeDepletingRange * ((D22_fuelConsumptionCsMode - D21_fuelConsumptionCdMode) / D22_fuelConsumptionCsMode); + var D27_zeroCO2EmissionsRange = D26_equivalentAllElectricRange; + + var D35_correctionFactorEC_SoC_TerminalCD = 1 / D15_chargingEffBatt; + var D36_electricEnergyCdModeTerminal = cdResult.ElectricEnergyConsumption * D35_correctionFactorEC_SoC_TerminalCD; + var D39_electricEnergyConsumptionWeighted = D33_utilityFactor * D36_electricEnergyCdModeTerminal; + var D40_fuelConsumptionWeighted = cdResult.FuelData.Select(x => Tuple.Create(x, + D33_utilityFactor * cdResult.FuelConsumptionFinal(x.FuelType).TotalFuelConsumptionCorrected + + (1 - D33_utilityFactor) * csResult.FuelConsumptionFinal(x.FuelType).TotalFuelConsumptionCorrected)) + .ToDictionary(x => x.Item1, x => x.Item2); + + var retVal = new WeightedResult() { + Distance = cdResult.Distance, + Payload = cdResult.Payload, + CargoVolume = cdResult.CargoVolume, + PassengerCount = cdResult.PassengerCount, AverageSpeed = cdResult.AverageSpeed, - AverageDrivingSpeed = (cdResult.AverageDrivingSpeed + csResult.AverageDrivingSpeed) / 2.0, - FuelConsumption = cdResult.FuelData.Select(x => Tuple.Create(x, - (cdResult.FuelConsumptionFinal(x.FuelType).TotalFuelConsumptionCorrected + - csResult.FuelConsumptionFinal(x.FuelType).TotalFuelConsumptionCorrected) / 2.0)) - .ToDictionary(x => x.Item1, x => x.Item2), - ElectricEnergyConsumption = (cdResult.ElectricEnergyConsumption + csResult.ElectricEnergyConsumption) / 2.0, - CO2Total = (cdResult.CO2Total + csResult.CO2Total) / 2.0, - ActualChargeDepletingRange = cdResult.Distance, - EquivalentAllElectricRange = cdResult.Distance, - ZeroCO2EmissionsRange = cdResult.Distance, - UtilityFactor = 1 + AverageDrivingSpeed = cdResult.AverageDrivingSpeed, + ActualChargeDepletingRange = D25_actualChargeDepletingRange, + EquivalentAllElectricRange = D26_equivalentAllElectricRange, + ZeroCO2EmissionsRange = D27_zeroCO2EmissionsRange, + UtilityFactor = D33_utilityFactor, + ElectricEnergyConsumption = D39_electricEnergyConsumptionWeighted, + FuelConsumption = D40_fuelConsumptionWeighted, + CO2Total = D33_utilityFactor * cdResult.CO2Total + (1 - D33_utilityFactor) * csResult.CO2Total, + + AuxHeaterFuel = cdResult.AuxHeaterFuel, + ZEV_CO2 = + cdResult.AuxHeaterFuel != null && cdResult.ZEV_CO2 != null && + csResult.ZEV_FuelConsumption_AuxHtr != null + ? D33_utilityFactor * cdResult.ZEV_CO2 + (1 - D33_utilityFactor) * csResult.ZEV_CO2 + : null, + ZEV_FuelConsumption_AuxHtr = + cdResult.AuxHeaterFuel != null && cdResult.ZEV_FuelConsumption_AuxHtr != null && + csResult.ZEV_FuelConsumption_AuxHtr != null + ? D33_utilityFactor * cdResult.ZEV_FuelConsumption_AuxHtr + + (1 - D33_utilityFactor) * csResult.ZEV_FuelConsumption_AuxHtr + : null, }; + + return retVal; } public static IWeightedResult CalculateWeightedSummary(IList<IResultEntry> entries) { - // ToDo MQ 2022-12-12: add correct calculation method! - var first = entries.FirstOrDefault(); - if (first == null) { + if (entries == null || !entries.Any()) { return null; } - return new WeightedResult(first) { - AverageSpeed = first.AverageSpeed, - FuelConsumption = first.FuelData?.Select(x => Tuple.Create(x, - first.FuelConsumptionFinal(x.FuelType).TotalFuelConsumptionCorrected)) + + var fuels = entries.First().FuelData; + return new WeightedResult() { + AverageSpeed = null, + AverageDrivingSpeed = null, + Distance = entries.Sum(e => e.Distance * e.WeightingFactor), + Payload = entries.Sum(e => e.Payload * e.WeightingFactor), + CargoVolume = entries.All(e => e.CargoVolume != null) ? entries.Sum(e => e.CargoVolume * e.WeightingFactor) : 0.SI<CubicMeter>(), + PassengerCount = entries.All(e => e.PassengerCount != null) ? entries.Sum(e => e.PassengerCount.Value * e.WeightingFactor) : (double?)null, + FuelConsumption = fuels.Select(f => Tuple.Create(f, + entries.All(e => e.FuelConsumptionFinal(f.FuelType) != null) ? entries.Sum(e => + e.FuelConsumptionFinal(f.FuelType).TotalFuelConsumptionCorrected * e.WeightingFactor) : null)) .ToDictionary(x => x.Item1, x => x.Item2), - ElectricEnergyConsumption = first.ElectricEnergyConsumption, - CO2Total = first.CO2Total, - ActualChargeDepletingRange = first.Distance, - EquivalentAllElectricRange = first.Distance, - ZeroCO2EmissionsRange = first.Distance, - UtilityFactor = 1, - - AuxHeaterFuel = first.AuxHeaterFuel, - ZEV_CO2 = first.ZEV_CO2, - ZEV_FuelConsumption_AuxHtr = first.ZEV_FuelConsumption_AuxHtr + ElectricEnergyConsumption = entries.All(e => e.ElectricEnergyConsumption != null) ? entries.Sum(e => e.ElectricEnergyConsumption * e.WeightingFactor) : null, + CO2Total = entries.All(e => e.CO2Total != null) ? entries.Sum(e => e.CO2Total * e.WeightingFactor) : null, + ActualChargeDepletingRange = entries.All(e => e.ActualChargeDepletingRange != null) ? entries.Sum(e => e.ActualChargeDepletingRange * e.WeightingFactor) : null, + EquivalentAllElectricRange = entries.All(e => e.EquivalentAllElectricRange != null) ? entries.Sum(e => e.EquivalentAllElectricRange * e.WeightingFactor) : null, + ZeroCO2EmissionsRange = entries.All(e => e.ZeroCO2EmissionsRange != null) ? entries.Sum(e => e.ZeroCO2EmissionsRange * e.WeightingFactor) : null, + UtilityFactor = double.NaN, + + AuxHeaterFuel = entries.First().AuxHeaterFuel, + ZEV_CO2 = entries.All(e => e.ZEV_CO2 != null) ? entries.Sum(e => e.ZEV_CO2 * e.WeightingFactor) : null, + ZEV_FuelConsumption_AuxHtr = entries.All(e => e.ZEV_FuelConsumption_AuxHtr != null) ? entries.Sum(e => e.ZEV_FuelConsumption_AuxHtr * e.WeightingFactor) : null }; } public static IWeightedResult CalculateWeightedSummary(IList<IOVCResultEntry> entries) { - // ToDo MQ 2022-12-12: add correct calculation method! - var cdResult = entries.First().ChargeDepletingResult; - var csResult = entries.First().ChargeSustainingResult; - return new WeightedResult(cdResult) { - AverageSpeed = cdResult.AverageSpeed, - FuelConsumption = cdResult.FuelData.Select(x => Tuple.Create(x, - (cdResult.FuelConsumptionFinal(x.FuelType).TotalFuelConsumptionCorrected + - csResult.FuelConsumptionFinal(x.FuelType).TotalFuelConsumptionCorrected) / 2.0)) + if (entries == null || !entries.Any()) { + return null; + } + + if (entries.Any(e => e.Weighted == null)) { + return null; + } + + var fuels = entries.First().ChargeDepletingResult.FuelData; + return new WeightedResult() { + AverageSpeed = null, + AverageDrivingSpeed = null, + Distance = entries.Sum(e => e.ChargeDepletingResult.Distance * e.ChargeDepletingResult.WeightingFactor), + Payload = entries.Sum(e => e.ChargeDepletingResult.Payload * e.ChargeDepletingResult.WeightingFactor), + CargoVolume = entries.All(e => e.ChargeDepletingResult.CargoVolume != null) ? entries.Sum(e => e.ChargeDepletingResult.CargoVolume * e.ChargeDepletingResult.WeightingFactor) : 0.SI<CubicMeter>(), + PassengerCount = entries.All(e => e.ChargeDepletingResult.PassengerCount != null) ? entries.Sum(e => e.ChargeDepletingResult.PassengerCount.Value * e.ChargeDepletingResult.WeightingFactor) : (double?)null, + FuelConsumption = fuels.Select(f => Tuple.Create(f, + entries.Sum(e => + e.Weighted.FuelConsumption[f] * e.ChargeDepletingResult.WeightingFactor))) .ToDictionary(x => x.Item1, x => x.Item2), - ElectricEnergyConsumption = (cdResult.ElectricEnergyConsumption + csResult.ElectricEnergyConsumption) / 2.0, - CO2Total = (cdResult.CO2Total + csResult.CO2Total) / 2.0, - ActualChargeDepletingRange = cdResult.Distance, - EquivalentAllElectricRange = cdResult.Distance, - ZeroCO2EmissionsRange = cdResult.Distance, - UtilityFactor = 1 + ElectricEnergyConsumption = entries.Sum(e => e.Weighted.ElectricEnergyConsumption * e.ChargeDepletingResult.WeightingFactor), + CO2Total = entries.Sum(e => e.Weighted.CO2Total * e.ChargeDepletingResult.WeightingFactor), + ActualChargeDepletingRange = entries.Sum(e => e.Weighted.ActualChargeDepletingRange * e.ChargeDepletingResult.WeightingFactor), + EquivalentAllElectricRange = entries.Sum(e => e.Weighted.EquivalentAllElectricRange * e.ChargeDepletingResult.WeightingFactor), + ZeroCO2EmissionsRange = entries.Sum(e => e.Weighted.ZeroCO2EmissionsRange * e.ChargeDepletingResult.WeightingFactor), + UtilityFactor = double.NaN, + + AuxHeaterFuel = entries.First().ChargeDepletingResult.AuxHeaterFuel, + ZEV_CO2 = entries.All(e => e.Weighted.ZEV_CO2 != null) ? entries.Sum(e => e.Weighted.ZEV_CO2 * e.ChargeDepletingResult.WeightingFactor) : null, + ZEV_FuelConsumption_AuxHtr = entries.All(e => e.Weighted.ZEV_FuelConsumption_AuxHtr != null) ? entries.Sum(e => e.Weighted.ZEV_FuelConsumption_AuxHtr * e.ChargeDepletingResult.WeightingFactor) : null, }; } diff --git a/VectoCore/VectoCore/Models/Declaration/VehicleOperation/MileageLookup.cs b/VectoCore/VectoCore/Models/Declaration/VehicleOperation/MileageLookup.cs index c164201451..40c72e64b6 100644 --- a/VectoCore/VectoCore/Models/Declaration/VehicleOperation/MileageLookup.cs +++ b/VectoCore/VectoCore/Models/Declaration/VehicleOperation/MileageLookup.cs @@ -30,25 +30,28 @@ namespace TUGraz.VectoCore.Models.Declaration.VehicleOperation var annualMileage = tableRow.ParseDouble(col).SI(Unit.SI.Kilo.Meter).Cast<Meter>(); Data.Add(Tuple.Create<string, MissionType>(group, mission), new MileageEntry() { - annualMileage = annualMileage, - workingDaysPerYear = workingDays, - dailyMileage = annualMileage / workingDays, + AnnualMileage = annualMileage, + WorkingDaysPerYear = workingDays, + DailyMileage = annualMileage / workingDays, }); } } } #endregion - + public MileageEntry Lookup(VehicleClass hdvClass, MissionType mission) + { + return Lookup(hdvClass.GetClassNumber(), mission); + } public struct MileageEntry { - public Meter annualMileage; - public double workingDaysPerYear; - public Meter dailyMileage; + public Meter AnnualMileage { get; internal set; } + public double WorkingDaysPerYear { get; internal set; } + public Meter DailyMileage { get; internal set; } } } } diff --git a/VectoCore/VectoCore/Models/Declaration/VehicleOperation/RealWorldUsageFactors.cs b/VectoCore/VectoCore/Models/Declaration/VehicleOperation/RealWorldUsageFactors.cs new file mode 100644 index 0000000000..7c253dfcb3 --- /dev/null +++ b/VectoCore/VectoCore/Models/Declaration/VehicleOperation/RealWorldUsageFactors.cs @@ -0,0 +1,42 @@ +using System.Data; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.Models.Declaration.VehicleOperation +{ + public class RealWorldUsageFactors : LookupData<string, RealWorldUsageFactors.Entry> + { + #region Overrides of LookupData + + protected override string ResourceId => "TUGraz.VectoCore.Resources.Declaration.VehicleOperation.RealWorldUsageFactors.csv"; + protected override string ErrorMessage => "Error looking up RealWorld Usage Factors"; + protected override void ParseData(DataTable table) + { + foreach (DataRow tableRow in table.Rows) { + var group = tableRow.Field<string>("vehiclegroup"); + var startSoCBeforeMission = tableRow.ParseDouble("startsocbeforemission"); + var stationaryChargingDuringMission = tableRow.ParseDouble("stationarychargingduringmission"); + Data.Add(group, new Entry() { + StartSoCBeforeMission = startSoCBeforeMission, + StationaryChargingDuringMission = stationaryChargingDuringMission, + }); + + } + } + + #endregion + + public Entry Lookup(VehicleClass hdvClass) + { + return Lookup(hdvClass.GetClassNumber()); + } + + public struct Entry + { + public double StartSoCBeforeMission { get; internal set; } + + public double StationaryChargingDuringMission { get; internal set; } + } + + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/VehicleOperation/StationaryChargingLookup.cs b/VectoCore/VectoCore/Models/Declaration/VehicleOperation/StationaryChargingLookup.cs index 98bddf97c8..7b713c32a4 100644 --- a/VectoCore/VectoCore/Models/Declaration/VehicleOperation/StationaryChargingLookup.cs +++ b/VectoCore/VectoCore/Models/Declaration/VehicleOperation/StationaryChargingLookup.cs @@ -9,7 +9,7 @@ namespace TUGraz.VectoCore.Models.Declaration.VehicleOperation { - public abstract class StationaryChargingLookup : LookupData<string, MissionType, double> + public abstract class StationaryChargingLookup<T> : LookupData<string, MissionType, double> { protected override void ParseData(DataTable table) @@ -28,14 +28,16 @@ namespace TUGraz.VectoCore.Models.Declaration.VehicleOperation } } - public double Lookup(VehicleClass hdvClass, MissionType mission) + public T Lookup(VehicleClass hdvClass, MissionType mission) { - return Lookup(hdvClass.GetClassNumber(), mission); + return ConvertValue(Lookup(hdvClass.GetClassNumber(), mission)); } + + protected abstract T ConvertValue(double val); } - public class StationaryChargingDurationPerEventLookup : StationaryChargingLookup + public class StationaryChargingDurationPerEventLookup : StationaryChargingLookup<Second> { #region Overrides of LookupData @@ -47,11 +49,19 @@ namespace TUGraz.VectoCore.Models.Declaration.VehicleOperation #endregion + #region Overrides of StationaryChargingLookup<Second> + + protected override Second ConvertValue(double val) + { + return val.SI(Unit.SI.Hour).Cast<Second>(); + } + + #endregion } - public class StationaryChargingFromInfrastructureLookup : StationaryChargingLookup + public class StationaryChargingPowerFromInfrastructureLookup : StationaryChargingLookup<Watt> { #region Overrides of LookupData @@ -61,10 +71,19 @@ namespace TUGraz.VectoCore.Models.Declaration.VehicleOperation protected override string ErrorMessage => "Error looking up stationary charging power from infrastructure"; #endregion + + #region Overrides of StationaryChargingLookup<Watt> + + protected override Watt ConvertValue(double val) + { + return val.SI(Unit.SI.Kilo.Watt).Cast<Watt>(); + } + + #endregion } - public class StationaryChargingEventsPerDayLookup : StationaryChargingLookup + public class StationaryChargingEventsPerDayLookup : StationaryChargingLookup<double> { #region Overrides of LookupData @@ -74,6 +93,15 @@ namespace TUGraz.VectoCore.Models.Declaration.VehicleOperation protected override string ErrorMessage => "Error looking up Number of charging events during mission"; #endregion + + #region Overrides of StationaryChargingLookup<double> + + protected override double ConvertValue(double val) + { + return val; + } + + #endregion } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Declaration/VehicleOperation/VehicleOperationLookup.cs b/VectoCore/VectoCore/Models/Declaration/VehicleOperation/VehicleOperationLookup.cs index 043737b0db..eba992ce4e 100644 --- a/VectoCore/VectoCore/Models/Declaration/VehicleOperation/VehicleOperationLookup.cs +++ b/VectoCore/VectoCore/Models/Declaration/VehicleOperation/VehicleOperationLookup.cs @@ -11,33 +11,38 @@ namespace TUGraz.VectoCore.Models.Declaration.VehicleOperation private StationaryChargingDurationPerEventLookup _chargingDurationLookup = new StationaryChargingDurationPerEventLookup(); - private StationaryChargingFromInfrastructureLookup _chargingFromInfrastructureLookup = - new StationaryChargingFromInfrastructureLookup(); + private StationaryChargingPowerFromInfrastructureLookup _chargingPowerFromInfrastructureLookup = + new StationaryChargingPowerFromInfrastructureLookup(); private StationaryChargingEventsPerDayLookup _numberOfChargingEventsLookup = new StationaryChargingEventsPerDayLookup(); + private RealWorldUsageFactors _realWorldUsageFactors = new RealWorldUsageFactors(); - public MileageLookup.MileageEntry LookupMileage(VehicleClass hdvClass, MissionType mission) + public VehicleOperationData LookupVehicleOperation(VehicleClass hdvClass, MissionType mission) { - return _mileageLookup.Lookup(hdvClass.GetClassNumber(), mission); + return new VehicleOperationData() { + Mileage = _mileageLookup.Lookup(hdvClass, mission), + StationaryChargingMaxPwrInfrastructure = _chargingPowerFromInfrastructureLookup.Lookup(hdvClass, mission), + StationaryChargingDuringMission_AvgDurationPerEvent = _chargingDurationLookup.Lookup(hdvClass, mission), + StationaryChargingDuringMission_NbrEvents = _numberOfChargingEventsLookup.Lookup(hdvClass, mission), + RealWorldUsageFactors = _realWorldUsageFactors.Lookup(hdvClass), + }; } - public Second LookupChargingDurationPerEvent(VehicleClass hdvClass, MissionType mission) + public class VehicleOperationData { - return _chargingDurationLookup.Lookup(hdvClass, mission).SI(Unit.SI.Hour).Cast<Second>(); - } + public MileageLookup.MileageEntry Mileage { get; internal set; } - public Watt LookupMaxChargingPower(VehicleClass hdvClass, MissionType mission) - { - return _chargingFromInfrastructureLookup.Lookup(hdvClass, mission).SI(Unit.SI.Kilo.Watt).Cast<Watt>(); - } + public Watt StationaryChargingMaxPwrInfrastructure { get; internal set; } - public double LookupChargingEventsPerDay(VehicleClass hdvClass, MissionType mission) - { - return _numberOfChargingEventsLookup.Lookup(hdvClass, mission); - } + public Second StationaryChargingDuringMission_AvgDurationPerEvent { get; internal set; } + + public double StationaryChargingDuringMission_NbrEvents { get; internal set; } + public RealWorldUsageFactors.Entry RealWorldUsageFactors { get; internal set; } + + } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs index 5b8fa0df2a..08d2d4715a 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs @@ -189,6 +189,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Data public OvcHevMode OVCMode { get; internal set; } + public Watt MaxChargingPower { get; internal set; } + [JsonIgnore] public IIterativeRunStrategy IterativeRunStrategy { get; internal set; } = new DefaultIterativeStrategy(); @@ -409,10 +411,4 @@ namespace TUGraz.VectoCore.Models.Simulation.Data public Meter FanDiameter; } - public class VehicleOperationData - { - private double AnnualMileage; - private double MissionSpecificMileage; - - } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/DeclarationReport.cs b/VectoCore/VectoCore/OutputData/DeclarationReport.cs index 09bd8e4032..35569dfb01 100644 --- a/VectoCore/VectoCore/OutputData/DeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/DeclarationReport.cs @@ -111,6 +111,8 @@ namespace TUGraz.VectoCore.OutputData double? PassengerCount { get; set; } VehicleClass VehicleClass { get; set; } + Watt MaxChargingPower { get; set; } + double WeightingFactor { get; } Meter ActualChargeDepletingRange { get; set; } @@ -250,7 +252,8 @@ namespace TUGraz.VectoCore.OutputData CargoVolume = runData.VehicleData.CargoVolume, VehicleClass = runData.Mission?.BusParameter?.BusGroup ?? runData.VehicleData.VehicleClass, //runData.VehicleData.VehicleClass, - PassengerCount = runData.VehicleData.PassengerCount + PassengerCount = runData.VehicleData.PassengerCount, + MaxChargingPower = runData.MaxChargingPower, }; lock (Results) { Results.Add(entry); diff --git a/VectoCore/VectoCore/OutputData/OvcResultEntry.cs b/VectoCore/VectoCore/OutputData/OvcResultEntry.cs index 63df37df56..463dbdfe1c 100644 --- a/VectoCore/VectoCore/OutputData/OvcResultEntry.cs +++ b/VectoCore/VectoCore/OutputData/OvcResultEntry.cs @@ -18,19 +18,13 @@ namespace TUGraz.VectoCore.OutputData public class WeightedResult : IWeightedResult { - public WeightedResult(IResultEntry cdResult) - { - ChargeDepletingResult = cdResult; - } - - protected IResultEntry ChargeDepletingResult; #region Implementation of IWeightedResult - public Meter Distance => ChargeDepletingResult.Distance; - public Kilogram Payload => ChargeDepletingResult.Payload; - public CubicMeter CargoVolume => ChargeDepletingResult.CargoVolume; - public double? PassengerCount => ChargeDepletingResult.PassengerCount; + public Meter Distance { get; internal set; } + public Kilogram Payload { get; internal set; } + public CubicMeter CargoVolume { get; internal set; } + public double? PassengerCount { get; internal set; } public MeterPerSecond AverageSpeed { get; internal set; } public MeterPerSecond AverageDrivingSpeed { get; internal set; } diff --git a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs index e35310450e..55b47f28a5 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs @@ -88,6 +88,7 @@ namespace TUGraz.VectoCore.OutputData.XML public double? PassengerCount { get; set; } public VehicleClass VehicleClass { get; set; } + public Watt MaxChargingPower { get; set; } public MeterPerSecond AverageSpeed { get; private set; } diff --git a/VectoCore/VectoCore/Resources/Declaration/VehicleOperation/RealWorldUsageFactors.csv b/VectoCore/VectoCore/Resources/Declaration/VehicleOperation/RealWorldUsageFactors.csv new file mode 100644 index 0000000000..a75e1e6dd1 --- /dev/null +++ b/VectoCore/VectoCore/Resources/Declaration/VehicleOperation/RealWorldUsageFactors.csv @@ -0,0 +1,24 @@ +Vehicle Group , Start SoC before Mission , Stationary charging during mission +53 , 0.75 , 0.50 +54 , 0.75 , 0.50 +1s , 0.75 , 0.50 +1 , 0.75 , 0.50 +2 , 0.75 , 0.50 +3 , 0.75 , 0.50 +4 , 0.75 , 0.50 +5 , 0.75 , 0.50 +9 , 0.75 , 0.50 +10 , 0.75 , 0.50 +11 , 0.75 , 0.50 +12 , 0.75 , 0.50 +16 , 0.75 , 0.50 +31 , 0.90 , 0.90 +32 , 0.90 , 0.50 +33 , 0.90 , 0.90 +34 , 0.90 , 0.50 +35 , 0.90 , 0.90 +36 , 0.90 , 0.50 +37 , 0.90 , 0.90 +38 , 0.90 , 0.50 +39 , 0.90 , 0.90 +40 , 0.90 , 0.50 diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj index d1b9628c67..528f68e9d0 100644 --- a/VectoCore/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore/VectoCore.csproj @@ -61,6 +61,7 @@ <None Remove="Resources\Declaration\VAUXBus\DEFAULT_2-Cylinder_1-Stage_650ccm.acmp" /> <None Remove="Resources\Declaration\VAUXBus\DEFAULT_2-Cylinder_2-Stage_398ccm.acmp" /> <None Remove="Resources\Declaration\VAUXBus\DEFAULT_3-Cylinder_2-Stage_598ccm.acmp" /> + <None Remove="Resources\Declaration\VehicleOperation\RealWorldUsageFactors.csv" /> <None Remove="Resources\MockupCIFResults.xml" /> <None Remove="Resources\MockupMRFResults.xml" /> <None Remove="Resources\XSD\VectoDeclarationDefinitions.2.2.1.xsd" /> diff --git a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs index d9f6e0d7aa..7c64426890 100644 --- a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs +++ b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs @@ -2416,8 +2416,8 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration [TestCase(VehicleClass.Class53, MissionType.UrbanDelivery, 4)] public void VehicleOperationLookupChargingEventsLorry(VehicleClass hdvClass, MissionType mission, double expected) { - var val = DeclarationData.VehicleOperation.LookupChargingEventsPerDay(hdvClass, mission); - Assert.AreEqual(expected, val); + var val = DeclarationData.VehicleOperation.LookupVehicleOperation(hdvClass, mission); + Assert.AreEqual(expected, val.StationaryChargingDuringMission_NbrEvents); } [TestCase(VehicleClass.Class1s, MissionType.RegionalDelivery, 0.5)] @@ -2426,8 +2426,8 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration [TestCase(VehicleClass.Class53, MissionType.UrbanDelivery, 0.5)] public void VehicleOperationLookupChargingDurationLorry(VehicleClass hdvClass, MissionType mission, double expected) { - var val = DeclarationData.VehicleOperation.LookupChargingDurationPerEvent(hdvClass, mission); - Assert.AreEqual(expected * 3600, val.Value()); //stored in seconds + var val = DeclarationData.VehicleOperation.LookupVehicleOperation(hdvClass, mission); + Assert.AreEqual(expected * 3600, val.StationaryChargingDuringMission_AvgDurationPerEvent.Value()); //stored in seconds } [TestCase(VehicleClass.Class1s, MissionType.RegionalDelivery, 250)] @@ -2436,8 +2436,8 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration [TestCase(VehicleClass.Class53, MissionType.UrbanDelivery, 250)] public void VehicleOperationLookupMaxChargingPowerLorry(VehicleClass hdvClass, MissionType mission, double expected) { - var val = DeclarationData.VehicleOperation.LookupMaxChargingPower(hdvClass, mission); - Assert.AreEqual(expected * 1000, val.Value()); //stored in watt + var val = DeclarationData.VehicleOperation.LookupVehicleOperation(hdvClass, mission); + Assert.AreEqual(expected * 1000, val.StationaryChargingMaxPwrInfrastructure.Value()); //stored in watt } [TestCase(VehicleClass.Class1s, MissionType.RegionalDelivery, 80000, 320)] @@ -2446,9 +2446,9 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration [TestCase(VehicleClass.Class53, MissionType.UrbanDelivery, 60000, 240)] public void VehicleOperationLookupMileageLorry(VehicleClass hdvClass, MissionType mission, double expectedAnnual, double expectedDaily) { - var val = DeclarationData.VehicleOperation.LookupMileage(hdvClass, mission); - Assert.AreEqual(expectedAnnual * 1000, val.annualMileage.Value()); //stored in meter - Assert.AreEqual(expectedDaily * 1000, val.dailyMileage.Value()); //stored in meter + var val = DeclarationData.VehicleOperation.LookupVehicleOperation(hdvClass, mission); + Assert.AreEqual(expectedAnnual * 1000, val.Mileage.AnnualMileage.Value()); //stored in meter + Assert.AreEqual(expectedDaily * 1000, val.Mileage.DailyMileage.Value()); //stored in meter } @@ -2458,20 +2458,9 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration public void VehicleOperationHeavyLorryFail(VehicleClass hdvClass, MissionType mission) { Assert.Throws<VectoException>(() => { - DeclarationData.VehicleOperation.LookupChargingDurationPerEvent(hdvClass, mission); + DeclarationData.VehicleOperation.LookupVehicleOperation(hdvClass, mission); }); - Assert.Throws<VectoException>(() => { - DeclarationData.VehicleOperation.LookupChargingEventsPerDay(hdvClass, mission); - }); - - Assert.Throws<VectoException>(() => { - DeclarationData.VehicleOperation.LookupMaxChargingPower(hdvClass, mission); - }); - - Assert.Throws<VectoException>(() => { - DeclarationData.VehicleOperation.LookupMileage(hdvClass, mission); - }); } } } \ No newline at end of file -- GitLab