diff --git a/VectoCommon/VectoCommon/Utils/VectoMath.cs b/VectoCommon/VectoCommon/Utils/VectoMath.cs index ef7372a7fc1f700677817b56629f7ed8a75ec378..e3c10c4302dca7c8666acebd50fc14500329ec2d 100644 --- a/VectoCommon/VectoCommon/Utils/VectoMath.cs +++ b/VectoCommon/VectoCommon/Utils/VectoMath.cs @@ -564,10 +564,12 @@ namespace TUGraz.VectoCommon.Utils var smallerX = x - DoubleExtensionMethods.Tolerance; var biggerX = x + DoubleExtensionMethods.Tolerance; - if ((P1.Y < smallerY && P2.Y < smallerY && P3.Y < smallerY) - || (P1.X < smallerX && P2.X < smallerX && P3.X < smallerX) - || (P1.X > biggerX && P2.X > biggerX && P3.X > biggerX) - || (P1.Y > biggerY && P2.Y > biggerY && P3.Y > biggerY)) { + var aboveTriangle = P1.Y < smallerY && P2.Y < smallerY && P3.Y < smallerY; + var belowTriangle = P1.Y > biggerY && P2.Y > biggerY && P3.Y > biggerY; + var leftOfTriangle = P1.X > biggerX && P2.X > biggerX && P3.X > biggerX; + var rightOfTriangle = P1.X < smallerX && P2.X < smallerX && P3.X < smallerX; + + if (aboveTriangle || rightOfTriangle || leftOfTriangle || belowTriangle) { return false; } diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs index da1cacd25562735ec6d7ddd354728fa139f2c851..19d015b541a80c3718189125ec065210c939c25f 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs @@ -596,21 +596,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON } if (auxData.Type == AuxiliaryType.Fan) { - DeclarationData.Fan.GetTechnologies(); - switch (tech) { - case "Crankshaft mounted - Electronically controlled visco clutch (Default)": - auxData.Technology.Add("Crankshaft mounted - Electronically controlled visco clutch"); - break; - case "Crankshaft mounted - On/Off clutch": - auxData.Technology.Add("Crankshaft mounted - On/off clutch"); - break; - case "Belt driven or driven via transm. - On/Off clutch": - auxData.Technology.Add("Belt driven or driven via transm. - On/off clutch"); - break; - default: - auxData.Technology.Add(tech); - break; - } + auxData.Technology.Add(MapLegacyFanTechnologies(tech)); } var auxFile = aux["Path"]; @@ -625,6 +611,26 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON return retVal; } + private static string MapLegacyFanTechnologies(string tech) + { + string newTech; + switch (tech) { + case "Crankshaft mounted - Electronically controlled visco clutch (Default)": + newTech = "Crankshaft mounted - Electronically controlled visco clutch"; + break; + case "Crankshaft mounted - On/Off clutch": + newTech = "Crankshaft mounted - On/off clutch"; + break; + case "Belt driven or driven via transm. - On/Off clutch": + newTech = "Belt driven or driven via transm. - On/off clutch"; + break; + default: + newTech = tech; + break; + } + return newTech; + } + #endregion #region AdvancedAuxiliaries diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs index ebfc452bb7db77d454e3c0351bf43f02ccce2664..7d2f64e0de6e6b511db0b0a8a1f1f86bf267409b 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs @@ -36,6 +36,7 @@ using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Configuration; using TUGraz.VectoCore.Models.Simulation.DataBus; using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; namespace TUGraz.VectoCore.Models.SimulationComponent.Impl { @@ -47,7 +48,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl public override IGearbox Gearbox { get { return _gearbox; } - set { + set + { _gearbox = value as ATGearbox; if (_gearbox == null) { throw new VectoException("AT Shift strategy can only handle AT gearboxes, given: {0}", value.GetType()); @@ -147,20 +149,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl } // EMERGENCY SHIFTS --------------------------------------- - // Emergency Downshift: if lower than engine idle speed - if (inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { - Log.Debug("engine speed would fall below idle speed - shift down"); - Downshift(absTime, gear); - return true; - } - // Emergency Upshift: if higher than engine rated speed - if (inAngularVelocity.IsGreaterOrEqual(ModelData.Gears[gear].MaxSpeed ?? DataBus.EngineRatedSpeed)) { - // check if upshift is possible - if (!ModelData.Gears.ContainsKey(gear + 1)) { - return false; - } - Log.Debug("engine speed would be above max speed / rated speed - shift up"); - Upshift(absTime, gear); + if (CheckEmergencyShift(absTime, inAngularVelocity, gear)) { return true; } @@ -179,6 +168,27 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return false; } + private bool CheckEmergencyShift(Second absTime, PerSecond inAngularVelocity, uint gear) + { +// Emergency Downshift: if lower than engine idle speed + if (inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) { + Log.Debug("engine speed would fall below idle speed - shift down"); + Downshift(absTime, gear); + return true; + } + // Emergency Upshift: if higher than engine rated speed + if (inAngularVelocity.IsGreaterOrEqual(ModelData.Gears[gear].MaxSpeed ?? DataBus.EngineRatedSpeed)) { + // check if upshift is possible + if (!ModelData.Gears.ContainsKey(gear + 1)) { + return false; + } + Log.Debug("engine speed would be above max speed / rated speed - shift up"); + Upshift(absTime, gear); + return true; + } + return false; + } + [SuppressMessage("ReSharper", "UnusedParameter.Local")] private bool CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime) @@ -191,17 +201,63 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var currentGear = ModelData.Gears[gear]; if (_gearbox.TorqueConverterLocked || currentGear.HasLockedGear) { + var result = CheckUpshiftToLocked(absTime, outAngularVelocity, inTorque, inAngularVelocity, gear); + if (result.HasValue) { + return result.Value; + } + } + + // UPSHIFT - Special rule for 1C -> 2C + if (!_gearbox.TorqueConverterLocked && ModelData.Gears.ContainsKey(gear + 1) && + ModelData.Gears[gear + 1].HasTorqueConverter && outAngularVelocity.IsGreater(0)) { + var result = CheckUpshiftTcTc(absTime, outTorque, outAngularVelocity, gear, currentGear); + if (result.HasValue) { + return result.Value; + } + } + return false; + } + + private bool? CheckUpshiftTcTc(Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity, uint gear, + GearData currentGear) + { +// C -> C+1 + var nextGear = ModelData.Gears[gear + 1]; + var gearRatio = nextGear.TorqueConverterRatio / currentGear.TorqueConverterRatio; + var minEngineSpeed = VectoMath.Min(700.RPMtoRad(), gearRatio * (DataBus.EngineN80hSpeed - 150.RPMtoRad())); + + var nextGearboxInSpeed = outAngularVelocity * nextGear.TorqueConverterRatio; + var nextGearboxInTorque = outTorque / nextGear.TorqueConverterRatio; + var tcOperatingPoint = _gearbox.TorqueConverter.FindOperatingPoint(nextGearboxInTorque, nextGearboxInSpeed); + + var engineSpeedOverMin = tcOperatingPoint.InAngularVelocity.IsGreater(minEngineSpeed); + + var reachableAcceleration = EstimateAccelerationForGear(gear + 1, outAngularVelocity); + var minAcceleration = VectoMath.Min(ModelData.TorqueConverterData.CCUpshiftMinAcceleration, + DataBus.DriverAcceleration); + var minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration); + + if (engineSpeedOverMin && minAccelerationReachable) { + Upshift(absTime, gear); + return true; + } + return null; + } + + private bool? CheckUpshiftToLocked(Second absTime, PerSecond outAngularVelocity, NewtonMeter inTorque, + PerSecond inAngularVelocity, uint gear) + { // UPSHIFT - General Rule // L -> L+1 // C -> L var nextGear = _gearbox.TorqueConverterLocked ? gear + 1 : gear; if (!ModelData.Gears.ContainsKey(nextGear)) { - return false; + return false; } var nextEngineSpeed = outAngularVelocity * ModelData.Gears[nextGear].Ratio; if (nextEngineSpeed.IsEqual(0)) { - return false; + return false; } var currentEnginePower = inTorque * inAngularVelocity; @@ -222,33 +278,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl Upshift(absTime, gear); return true; } - } - - // UPSHIFT - Special rule for 1C -> 2C - if (!_gearbox.TorqueConverterLocked && ModelData.Gears.ContainsKey(gear + 1) && - ModelData.Gears[gear + 1].HasTorqueConverter && outAngularVelocity.IsGreater(0)) { - // C -> C+1 - var nextGear = ModelData.Gears[gear + 1]; - var gearRatio = nextGear.TorqueConverterRatio / currentGear.TorqueConverterRatio; - var minEngineSpeed = VectoMath.Min(700.RPMtoRad(), gearRatio * (DataBus.EngineN80hSpeed - 150.RPMtoRad())); - - var nextGearboxInSpeed = outAngularVelocity * nextGear.TorqueConverterRatio; - var nextGearboxInTorque = outTorque / nextGear.TorqueConverterRatio; - var tcOperatingPoint = _gearbox.TorqueConverter.FindOperatingPoint(nextGearboxInTorque, nextGearboxInSpeed); - - var engineSpeedOverMin = tcOperatingPoint.InAngularVelocity.IsGreater(minEngineSpeed); - - var reachableAcceleration = EstimateAccelerationForGear(gear + 1, outAngularVelocity); - var minAcceleration = VectoMath.Min(ModelData.TorqueConverterData.CCUpshiftMinAcceleration, - DataBus.DriverAcceleration); - var minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration); - - if (engineSpeedOverMin && minAccelerationReachable) { - Upshift(absTime, gear); - return true; - } - } - return false; + return null; } /// <summary> diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs index c407266aeb7870562b92531c4ee65fbf5502c9af..894dd1b7096ba7193d40314f607a597d65863c86 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Driver.cs @@ -715,28 +715,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl var retVal = new OperatingPoint { Acceleration = acceleration, SimulationDistance = ds }; var actionRoll = !DataBus.ClutchClosed(absTime); - var searchEngineSpeed = false; - Watt origDelta = null; - if (actionRoll) { - initialResponse.Switch(). - Case<ResponseDryRun>(r => origDelta = r.GearboxPowerRequest). - Case<ResponseFailTimeInterval>(r => origDelta = r.GearboxPowerRequest). - Default(r => { - throw new UnexpectedResponseException("SearchOperatingPoint: Unknown response type.", r); - }); - } else { - initialResponse.Switch(). - Case<ResponseOverload>(r => origDelta = r.Delta). - Case<ResponseEngineSpeedTooHigh>(r => { - searchEngineSpeed = true; - origDelta = r.DeltaEngineSpeed * 1.SI<NewtonMeter>(); - }). // search operating point in drive action after overload - Case<ResponseDryRun>(r => origDelta = coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad). - Default(r => { - throw new UnexpectedResponseException("SearchOperatingPoint: Unknown response type.", r); - }); - } + var origDelta = GetOrigDelta(initialResponse, coastingOrRoll, actionRoll); + + var searchEngineSpeed = initialResponse is ResponseEngineSpeedTooHigh; + var delta = origDelta; try { retVal.Acceleration = SearchAlgorithm.Search(acceleration, delta, @@ -752,7 +735,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl acc => { // calculate new time interval only when vehiclespeed and acceleration are != 0 // else: use same timeinterval as before. - if (!(acc.IsEqual(0) && DataBus.VehicleSpeed.IsEqual(0))) { + var vehicleDrivesAndAccelerates = !(acc.IsEqual(0) && DataBus.VehicleSpeed.IsEqual(0)); + if (vehicleDrivesAndAccelerates) { var tmp = ComputeTimeInterval(acc, ds); if (tmp.SimulationInterval.IsEqual(0.SI<Second>(), 1e-9.SI<Second>())) { throw new VectoSearchAbortedException( @@ -782,11 +766,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl abortCriterion: (response, cnt) => { var r = (ResponseDryRun)response; - if (r == null) { - return false; - } - - return !actionRoll && !ds.IsEqual(r.OperatingPoint.SimulationDistance); + return r != null && !actionRoll && !ds.IsEqual(r.OperatingPoint.SimulationDistance); }); } catch (VectoSearchAbortedException) { // search aborted, try to go ahead with the last acceleration @@ -802,6 +782,30 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return ComputeTimeInterval(retVal.Acceleration, retVal.SimulationDistance); } + private static Watt GetOrigDelta(IResponse initialResponse, bool coastingOrRoll, bool actionRoll) + { + Watt origDelta = null; + if (actionRoll) { + initialResponse.Switch(). + Case<ResponseDryRun>(r => origDelta = r.GearboxPowerRequest). + Case<ResponseFailTimeInterval>(r => origDelta = r.GearboxPowerRequest). + Default(r => { + throw new UnexpectedResponseException("SearchOperatingPoint: Unknown response type.", r); + }); + } else { + initialResponse.Switch(). + Case<ResponseOverload>(r => origDelta = r.Delta). + Case<ResponseEngineSpeedTooHigh>(r => { + origDelta = r.DeltaEngineSpeed * 1.SI<NewtonMeter>(); + }). // search operating point in drive action after overload + Case<ResponseDryRun>(r => origDelta = coastingOrRoll ? r.DeltaDragLoad : r.DeltaFullLoad). + Default(r => { + throw new UnexpectedResponseException("SearchOperatingPoint: Unknown response type.", r); + }); + } + return origDelta; + } + /// <summary> /// compute the acceleration and time-interval such that the vehicle's velocity approaches the given target velocity /// - first compute the acceleration to reach the targetVelocity within the given distance diff --git a/VectoCore/VectoCore/Utils/VectoCSVFile.cs b/VectoCore/VectoCore/Utils/VectoCSVFile.cs index 59a24a038afda03cb6240c3b8692e2a6d77d80c5..72ad52041301e8e2e387014c0b517774a0383ec7 100644 --- a/VectoCore/VectoCore/Utils/VectoCSVFile.cs +++ b/VectoCore/VectoCore/Utils/VectoCSVFile.cs @@ -38,6 +38,7 @@ using System.Linq; using System.Reflection; using System.Text; using System.Text.RegularExpressions; +using DocumentFormat.OpenXml.Spreadsheet; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; @@ -111,19 +112,13 @@ namespace TUGraz.VectoCore.Utils TrimWhiteSpace = true }; - string[] colsWithoutComment = { }; - - try { - var fields = p.ReadFields(); - if (fields == null) { - throw new CSVReadException("CSV Read Error: File was empty."); - } - colsWithoutComment = fields - .Select(l => l.Contains(Comment) ? l.Substring(0, l.IndexOf(Comment, StringComparison.Ordinal)) : l) - .ToArray(); - } catch (ArgumentNullException) { + var hdrFields = p.ReadFields(); + if (hdrFields == null) { throw new CSVReadException("CSV Read Error: File was empty."); } + var colsWithoutComment = hdrFields + .Select(l => l.Contains(Comment) ? l.Substring(0, l.IndexOf(Comment, StringComparison.Ordinal)) : l) + .ToArray(); double tmp; var columns = colsWithoutComment @@ -142,10 +137,7 @@ namespace TUGraz.VectoCore.Utils columns = colsWithoutComment.Select((_, i) => i.ToString()).ToList(); } - //var table = new DataTable(); - foreach (var col in columns) { - table.Columns.Add(col); - } + columns.ForEach(col => table.Columns.Add(col)); var lineNumber = 1; while (!p.EndOfData) {