// Copyright 2017 European Union. // Licensed under the EUPL (the 'Licence'); // // * You may not use this work except in compliance with the Licence. // * You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl // * Unless required by applicable law or agreed to in writing, // software distributed under the Licence is distributed on an "AS IS" basis, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // // See the LICENSE.txt for the specific language governing permissions and limitations. using System; using System.Collections.Generic; using System.Windows.Forms; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.BusAuxiliaries.DownstreamModules.Impl; using TUGraz.VectoCore.BusAuxiliaries.DownstreamModules.Impl.Electrics; using TUGraz.VectoCore.BusAuxiliaries.DownstreamModules.Impl.HVAC; using TUGraz.VectoCore.BusAuxiliaries.DownstreamModules.Impl.Pneumatics; using TUGraz.VectoCore.BusAuxiliaries.Interfaces; using TUGraz.VectoCore.BusAuxiliaries.Interfaces.DownstreamModules; using TUGraz.VectoCore.BusAuxiliaries.Interfaces.DownstreamModules.Electrics; using TUGraz.VectoCore.BusAuxiliaries.Interfaces.DownstreamModules.PneumaticSystem; using TUGraz.VectoCore.BusAuxiliaries.Util; namespace TUGraz.VectoCore.BusAuxiliaries { /// <summary> /// ''' Main entry point for the advanced auxiliary module. /// ''' This class represents slide number 17 titled Calculations of Cycle FC accounting for Smart Auxiliaries. /// ''' </summary> /// ''' <remarks></remarks> public class AdvancedAuxiliaries : IAdvancedAuxiliaries { protected internal AuxiliaryConfig auxConfig; // Supporting classes which may generate event messages private ICompressorMap compressorMap; private SSMTOOL ssmTool; private SSMTOOL ssmToolModule14; private IAlternatorMap alternatorMap; public IPneumaticActuationsMAP actuationsMap; private IFuelConsumptionMap fuelMap; // Classes which compose the model. private IM0_NonSmart_AlternatorsSetEfficiency M0; private IM0_5_SmartAlternatorSetEfficiency M05; private IM1_AverageHVACLoadDemand M1; private IM2_AverageElectricalLoadDemand M2; private IM3_AveragePneumaticLoadDemand M3; private IM4_AirCompressor M4; private IM5_SmartAlternatorSetGeneration M5; private IM6 M6; private IM7 M7; private IM8 M8; private IM9 M9; private IM10 M10; private IM11 M11; private IM12 M12; private IM13 M13; private IM14 M14; private string vectoDirectory; private HVACConstants hvacConstants; // Event Handler top level bubble. // Public Sub VectoEventHandler(ByRef sender As Object, message As String, messageType As AdvancedAuxiliaryMessageType) _ // Handles compressorMap.AuxiliaryEvent, alternatorMap.AuxiliaryEvent, ssmTool.Message, ssmToolModule14.Message // If Signals.AuxiliaryEventReportingLevel <= messageType Then // RaiseEvent AuxiliaryEvent(sender, message, messageType) // End If // End Sub // Constructor public AdvancedAuxiliaries() { VectoInputs = new VectoInputs(); Signals = new Signals(); } // Initialise Model public void Initialise(string IAuxPath, string vectoFilePath) { string auxPath; vectoDirectory = FilePathUtils.fPATH(vectoFilePath); auxPath = FilePathUtils.ResolveFilePath(vectoDirectory, IAuxPath); hvacConstants = new HVACConstants(VectoInputs.FuelDensity); Signals.CurrentCycleTimeInSeconds = 0; auxConfig = new AuxiliaryConfig(auxPath); // Pass some signals from config to Signals. ( These are stored in the configuration but shared in the signal distribution around modules ) Signals.SmartElectrics = auxConfig.ElectricalUserInputsConfig.SmartElectrical; Signals.StoredEnergyEfficiency = auxConfig.ElectricalUserInputsConfig.StoredEnergyEfficiency; Signals.SmartPneumatics = auxConfig.PneumaticUserInputsConfig.SmartAirCompression; Signals.PneumaticOverrunUtilisation = auxConfig.PneumaticAuxillariesConfig.OverrunUtilisationForCompressionFraction; alternatorMap = new CombinedAlternator(FilePathUtils.ResolveFilePath(vectoDirectory, auxConfig.ElectricalUserInputsConfig.AlternatorMap), Signals); actuationsMap = new PneumaticActuationsMap(FilePathUtils.ResolveFilePath(vectoDirectory, auxConfig.PneumaticUserInputsConfig.ActuationsMap)); compressorMap = new CompressorMap(FilePathUtils.ResolveFilePath(vectoDirectory, auxConfig.PneumaticUserInputsConfig.CompressorMap)); compressorMap.Initialise(); // fuelMap = New cMAP() // fuelMap.FilePath = FilePathUtils.ResolveFilePath(vectoDirectory, VectoInputs.FuelMap) // If Not fuelMap.ReadFile() Then // MessageBox.Show("Unable to read fuel map, aborting.") // Return // End If // fuelMap.Triangulate() fuelMap = VectoInputs.FuelMap; auxConfig.ElectricalUserInputsConfig.ElectricalConsumers.DoorDutyCycleFraction = GetDoorActuationTimeFraction(); // SSM HVAC var ssmPath = FilePathUtils.ResolveFilePath(vectoDirectory, auxConfig.HvacUserInputsConfig.SSMFilePath); var BusDatabase = FilePathUtils.ResolveFilePath(vectoDirectory, auxConfig.HvacUserInputsConfig.BusDatabasePath); ssmTool = new SSMTOOL(ssmPath, hvacConstants, auxConfig.HvacUserInputsConfig.SSMDisabled); // This duplicate SSM is being created for use in M14 as its properties will be dynamically changed at that point // to honour EngineWaste Heat Usage in Fueling calculations. ssmToolModule14 = new SSMTOOL(ssmPath, hvacConstants, auxConfig.HvacUserInputsConfig.SSMDisabled); if ((ssmTool.Load(ssmPath) == false || ssmToolModule14.Load(ssmPath) == false)) throw new Exception(string.Format("Unable to load the ssmTOOL with file {0}", ssmPath)); M0 = new M00Impl(auxConfig.ElectricalUserInputsConfig.ElectricalConsumers, alternatorMap, auxConfig.ElectricalUserInputsConfig.PowerNetVoltage.SI<Volt>(), Signals, ssmTool); IM0_5_SmartAlternatorSetEfficiency M05tmp = new M0_5Impl(M0, auxConfig.ElectricalUserInputsConfig.ElectricalConsumers, alternatorMap, auxConfig.ElectricalUserInputsConfig.ResultCardIdle, auxConfig.ElectricalUserInputsConfig.ResultCardTraction, auxConfig.ElectricalUserInputsConfig.ResultCardOverrun, Signals); M05 = M05tmp; M1 = new M01Impl(M0, auxConfig.ElectricalUserInputsConfig.AlternatorGearEfficiency, auxConfig.PneumaticUserInputsConfig.CompressorGearEfficiency, auxConfig.ElectricalUserInputsConfig.PowerNetVoltage.SI<Volt>(), Signals, ssmTool); M2 = new M02Impl(auxConfig.ElectricalUserInputsConfig.ElectricalConsumers, M0, auxConfig.ElectricalUserInputsConfig.AlternatorGearEfficiency, auxConfig.ElectricalUserInputsConfig.PowerNetVoltage.SI<Volt>(), Signals); M3 = new M03Impl(auxConfig.PneumaticUserInputsConfig, auxConfig.PneumaticAuxillariesConfig, actuationsMap, compressorMap, VectoInputs.VehicleWeightKG, VectoInputs.Cycle, Signals); M4 = new M04Impl(compressorMap, auxConfig.PneumaticUserInputsConfig.CompressorGearRatio, auxConfig.PneumaticUserInputsConfig.CompressorGearEfficiency, Signals); M5 = new M05Impl(M05tmp, auxConfig.ElectricalUserInputsConfig.PowerNetVoltage.SI<Volt>(), auxConfig.ElectricalUserInputsConfig.AlternatorGearEfficiency); M6 = new M06Impl(M1, M2, M3, M4, M5, Signals); M7 = new M07Impl(M5, M6, Signals); M8 = new M08Impl(M1, M6, M7, Signals); M9 = new M09Impl(M1, M4, M6, M8, fuelMap, auxConfig.PneumaticAuxillariesConfig, Signals); M10 = new M10Impl(M3, M9, Signals); M11 = new M11Impl(M1, M3, M6, M8, fuelMap, Signals); M12 = new M12Impl(M10, M11, Signals); M13 = new M13Impl(M10, M11, M12, Signals); M14 = new M14Impl(M13, ssmToolModule14, hvacConstants, Signals); } public ISignals Signals { get; set; } public IVectoInputs VectoInputs { get; set; } public event TUGraz.VectoCore.BusAuxiliaries.Interfaces.AuxiliaryEventEventHandler AuxiliaryEvent; public delegate void AuxiliaryEventEventHandler(ref object sender, string message, AdvancedAuxiliaryMessageType messageType); //public bool Configure(string filePath, string vectoFilePath) //{ // try { // frmAuxiliaryConfig frmAuxiliaryConfig = new frmAuxiliaryConfig(filePath, vectoFilePath); // frmAuxiliaryConfig.Show(); // if (frmAuxiliaryConfig.DialogResult != DialogResult.OK) { // return true; // } // return false; // } catch (Exception ex) { // return false; // } //} public bool CycleStep(Second seconds, ref string message) { try { M9.CycleStep(seconds); M10.CycleStep(seconds); M11.CycleStep(seconds); Signals.CurrentCycleTimeInSeconds += seconds.Value(); } catch (Exception ex) { MessageBox.Show("Exception: " + ex.Message + " Stack Trace: " + ex.StackTrace); return false; } return true; } public bool Running { get { throw new NotImplementedException(); } } public bool RunStart(string auxFilePath, string vectoFilePath) { try { Initialise(auxFilePath, vectoFilePath); } catch (Exception ex) { return false; } return true; } public bool RunStop(ref string message) { throw new NotImplementedException(); } public void ResetCalculations() { var modules = new List<IAbstractModule>() { M0, M05, M1, M2, M3, M4, M5, M6, M7, M8, M9, M10, M11, M12, M13, M14 }; foreach (var moduel in modules) moduel.ResetCalculations(); } public Kilogram TotalFuelGRAMS { get { if (M13 != null) return M14.TotalCycleFCGrams; else return 0.SI<Kilogram>(); } } public Liter TotalFuelLITRES { get { if (M14 != null) return M14.TotalCycleFCLitres; else return 0.SI<Liter>(); } } public string AuxiliaryName { get { return "BusAuxiliaries"; } } public string AuxiliaryVersion { get { return "Version 1.0 Beta"; } } // Helpers private double GetDoorActuationTimeFraction() { var actuationsMap = new PneumaticActuationsMap(FilePathUtils.ResolveFilePath(vectoDirectory, auxConfig.PneumaticUserInputsConfig.ActuationsMap)); var actuationsKey = new ActuationsKey("Park brake + 2 doors", VectoInputs.Cycle); var numActuations = actuationsMap.GetNumActuations(actuationsKey); var secondsPerActuation = auxConfig.ElectricalUserInputsConfig.DoorActuationTimeSecond; var doorDutyCycleFraction = (numActuations * secondsPerActuation) / (double)Signals.TotalCycleTimeSeconds; return doorDutyCycleFraction; } public bool ValidateAAUXFile(string filePath, ref string message) { var validResult = FilePathUtils.ValidateFilePath(filePath, ".aaux", ref message); return validResult; } // Diagnostics outputs for testing purposes in Vecto. // Eventually this can be removed or rendered non effective to reduce calculation load on the model. public double AA_NonSmartAlternatorsEfficiency { get { return M0.AlternatorsEfficiency; } } public Ampere AA_SmartIdleCurrent_Amps { get { return M05.SmartIdleCurrent; } } public double AA_SmartIdleAlternatorsEfficiency { get { return M05.AlternatorsEfficiencyIdleResultCard; } } public Ampere AA_SmartTractionCurrent_Amps { get { return M05.SmartTractionCurrent; } } public double AA_SmartTractionAlternatorEfficiency { get { return M05.AlternatorsEfficiencyTractionOnResultCard; } } public Ampere AA_SmartOverrunCurrent_Amps { get { return M05.SmartOverrunCurrent; } } public double AA_SmartOverrunAlternatorEfficiency { get { return M05.AlternatorsEfficiencyOverrunResultCard; } } public NormLiterPerSecond AA_CompressorFlowRate_LitrePerSec { get { return M4.GetFlowRate(); } } public bool AA_OverrunFlag { get { return M6.OverrunFlag; } } public int? AA_EngineIdleFlag { get { return Signals.EngineSpeed <= Signals.EngineIdleSpeed && (!Signals.ClutchEngaged || Signals.InNeutral) ? 1 : 0; } } public bool AA_CompressorFlag { get { return M8.CompressorFlag; } } public Kilogram AA_TotalCycleFC_Grams { get { return M14.TotalCycleFCGrams; } } public Liter AA_TotalCycleFC_Litres { get { return M14.TotalCycleFCLitres; } } public Watt AuxiliaryPowerAtCrankWatts { get { return M8.AuxPowerAtCrankFromElectricalHVACAndPneumaticsAncillaries; } } public Watt AA_AveragePowerDemandCrankHVACMechanicals { get { return M1.AveragePowerDemandAtCrankFromHVACMechanicalsWatts(); } } public Watt AA_AveragePowerDemandCrankHVACElectricals { get { return M1.AveragePowerDemandAtCrankFromHVACElectricsWatts(); } } public Watt AA_AveragePowerDemandCrankElectrics { get { return M2.GetAveragePowerAtCrankFromElectrics(); } } public Watt AA_AveragePowerDemandCrankPneumatics { get { return M3.GetAveragePowerDemandAtCrankFromPneumatics(); } } public Kilogram AA_TotalCycleFuelConsumptionCompressorOff { get { return M9.TotalCycleFuelConsumptionCompressorOffContinuously; } } public Kilogram AA_TotalCycleFuelConsumptionCompressorOn { get { return M9.TotalCycleFuelConsumptionCompressorOnContinuously; } } } }