diff --git a/VectoCommon/VectoCommon/Utils/VectoMath.cs b/VectoCommon/VectoCommon/Utils/VectoMath.cs index d7422f0806f899f5030573d655e420a217e3ccc6..58c55265c95570a7720cb0c61625005cc4b7ac2b 100644 --- a/VectoCommon/VectoCommon/Utils/VectoMath.cs +++ b/VectoCommon/VectoCommon/Utils/VectoMath.cs @@ -438,10 +438,10 @@ namespace TUGraz.VectoCommon.Utils /// <returns></returns> public bool IsInside(double x, double y, bool exact) { - if ((P1.Y < y && P2.Y < y && P3.Y < y) - || (P1.X < x && P2.X < x && P3.X < x) - || (P1.X > x && P2.X > x && P3.X > x) - || (P1.Y > y && P2.Y > y && P3.Y > y)) + if ((P1.Y.IsSmaller(y) && P2.Y.IsSmaller(y) && P3.Y.IsSmaller(y)) + || (P1.X.IsSmaller(x) && P2.X.IsSmaller(x) && P3.X.IsSmaller(x)) + || (P1.X.IsGreater(x) && P2.X.IsGreater(x) && P3.X.IsGreater(x)) + || (P1.Y.IsGreater(y) && P2.Y.IsGreater(y) && P3.Y.IsGreater(y))) return false; var v0X = P3.X - P1.X; diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs index ad28b8f6fa686c88435b04f62a2adc3d6a380d84..b2072fb3c0550293bca801894d1b5af075d63884 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs @@ -482,46 +482,16 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON }; var tech = aux.GetEx<string>("Technology"); - // Convert old Electric System to new format if (auxData.Type == AuxiliaryType.ElectricSystem) { if (aux["TechList"] == null || aux["TechList"].Any()) { auxData.Technology.Add("Standard technology"); - Log.Warn("Aux: Upgraded Electric System to new format: '{0}'", auxData.Technology.Last()); } else { auxData.Technology.Add("Standard technology - LED headlights, all"); - Log.Warn("Aux: Upgraded Electric System to new format: '{0}'", auxData.Technology.Last()); } } - // Convert old Steering Pump to new format if (auxData.Type == AuxiliaryType.SteeringPump) { - switch (tech) { - case "Variable displacement": - auxData.Technology.Add("Variable displacement elec. controlled"); - Log.Warn("Aux: Upgraded Steering Pump Technology from '{0}' to '{1}'", tech, auxData.Technology.Last()); - - break; - case "Hydraulic supported by electric": - auxData.Technology.Add("Dual displacement"); - Log.Warn("Aux: Upgraded Steering Pump Technology from '{0}' to '{1}'", tech, auxData.Technology.Last()); - break; - default: - auxData.Technology.Add(tech); - break; - } - } - - // Convert old Pneumatic System to new format - if (auxData.Type == AuxiliaryType.PneumaticSystem) { - auxData.Technology.Add("Medium Supply 1-stage"); - Log.Warn("Aux: Upgraded Pneumatic System Technology to '{0}'", tech, auxData.Technology.Last()); - } - - // Convert old HVAC to new format - if (auxData.Type == AuxiliaryType.HVAC) { - if (!string.IsNullOrWhiteSpace(tech)) { - Log.Warn("Aux: Upgraded HVAC Technology from '{0}' to '{1}'", tech, ""); - } + auxData.Technology.Add(tech); } if (auxData.Type == AuxiliaryType.Fan) { diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs index f91cea32aa1b5928647c23054a67989349e8b4de..7ff918b66b28b0b1ecc5017652d8087bc87fe7bf 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs @@ -248,7 +248,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter }; switch (auxType) { case AuxiliaryType.Fan: - aux.PowerDemand = DeclarationData.Fan.Lookup(mission, auxData.Technology.First()); + aux.PowerDemand = DeclarationData.Fan.Lookup(mission, auxData.Technology.FirstOrDefault()); aux.ID = Constants.Auxiliaries.IDs.Fan; break; case AuxiliaryType.SteeringPump: @@ -260,11 +260,11 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter aux.ID = Constants.Auxiliaries.IDs.HeatingVentilationAirCondition; break; case AuxiliaryType.PneumaticSystem: - aux.PowerDemand = DeclarationData.PneumaticSystem.Lookup(mission, auxData.Technology.First()); + aux.PowerDemand = DeclarationData.PneumaticSystem.Lookup(mission, auxData.Technology.FirstOrDefault()); aux.ID = Constants.Auxiliaries.IDs.PneumaticSystem; break; case AuxiliaryType.ElectricSystem: - aux.PowerDemand = DeclarationData.ElectricSystem.Lookup(mission, auxData.Technology.First()); + aux.PowerDemand = DeclarationData.ElectricSystem.Lookup(mission, auxData.Technology.FirstOrDefault()); aux.ID = Constants.Auxiliaries.IDs.ElectricSystem; break; default: diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs index 2acbfd927794d80dc9eab4d117318941f1b08d6e..94f64c6bfc185ba98a7db8aeb966147f7b8196f9 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs @@ -29,12 +29,8 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; using System.ComponentModel.DataAnnotations; -using System.Data; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Linq; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Configuration; @@ -59,7 +55,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine { var result = new FuelConsumptionResult(); // delaunay map needs is initialised with rpm, therefore the angularVelocity has to be converted. - var value = _fuelMap.Interpolate(torque.Value(), angularVelocity.AsRPM); + var value = _fuelMap.Interpolate(torque, angularVelocity); if (value.HasValue) { result.Value = value.Value.SI().Kilo.Gramm.Per.Second.Cast<KilogramPerSecond>(); return result; @@ -67,7 +63,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine if (allowExtrapolation) { result.Value = - _fuelMap.Extrapolate(torque.Value(), angularVelocity.AsRPM).SI().Kilo.Gramm.Per.Second.Cast<KilogramPerSecond>(); + _fuelMap.Extrapolate(torque, angularVelocity).SI().Kilo.Gramm.Per.Second.Cast<KilogramPerSecond>(); result.Extrapolated = true; return result; } @@ -76,58 +72,18 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine angularVelocity.AsRPM); } - [SuppressMessage("ReSharper", "MemberCanBePrivate.Local")] - public class FuelConsumptionEntry + public class Entry { - [Required, SIRange(0, 5000 * Constants.RPMToRad)] - public PerSecond EngineSpeed { get; set; } + [Required, SIRange(0, 5000 * Constants.RPMToRad)] public readonly PerSecond EngineSpeed; + [Required] public readonly NewtonMeter Torque; + [Required, SIRange(0, double.MaxValue)] public readonly KilogramPerSecond FuelConsumption; - [Required] - public NewtonMeter Torque { get; set; } - - [Required, SIRange(0, double.MaxValue)] - public KilogramPerSecond FuelConsumption { get; set; } - - #region Equality members - - public FuelConsumptionEntry(PerSecond engineSpeed, NewtonMeter torque, KilogramPerSecond fuelConsumption) + public Entry(PerSecond engineSpeed, NewtonMeter torque, KilogramPerSecond fuelConsumption) { EngineSpeed = engineSpeed; Torque = torque; FuelConsumption = fuelConsumption; } - - private bool Equals(FuelConsumptionEntry other) - { - return EngineSpeed.Equals(other.EngineSpeed) && Torque.Equals(other.Torque) && - FuelConsumption.Equals(other.FuelConsumption); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) { - return false; - } - if (ReferenceEquals(this, obj)) { - return true; - } - if (obj.GetType() != GetType()) { - return false; - } - return Equals((FuelConsumptionEntry)obj); - } - - public override int GetHashCode() - { - unchecked { - var hashCode = EngineSpeed.GetHashCode(); - hashCode = (hashCode * 397) ^ Torque.GetHashCode(); - hashCode = (hashCode * 397) ^ FuelConsumption.GetHashCode(); - return hashCode; - } - } - - #endregion } [DebuggerDisplay("{Value} (extrapolated: {Extrapolated})")] @@ -136,33 +92,5 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine public KilogramPerSecond Value; public bool Extrapolated; } - - #region Equality members - - protected bool Equals(FuelConsumptionMap other) - { - return Equals(_fuelMap, other._fuelMap); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) { - return false; - } - if (ReferenceEquals(this, obj)) { - return true; - } - if (obj.GetType() != GetType()) { - return false; - } - return Equals((FuelConsumptionMap)obj); - } - - public override int GetHashCode() - { - return _fuelMap != null ? _fuelMap.GetHashCode() : 0; - } - - #endregion } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMapReader.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMapReader.cs index fe85cbcdb6ed35785d938e57cedfa77b841a6107..beff9d855dda1d88a49bfa8834e7a5f5e080403c 100644 --- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMapReader.cs +++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMapReader.cs @@ -34,7 +34,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine foreach (DataRow row in data.Rows) { try { var entry = headerValid ? CreateFromColumNames(row) : CreateFromColumnIndizes(row); - delaunayMap.AddPoint(entry.Torque.Value(), headerValid ? row.ParseDouble(Fields.EngineSpeed) : row.ParseDouble(0), + delaunayMap.AddPoint(entry.Torque.Value(), + (headerValid ? row.ParseDouble(Fields.EngineSpeed) : row.ParseDouble(0)).RPMtoRad().Value(), entry.FuelConsumption.Value()); } catch (Exception e) { throw new VectoException(string.Format("Line {0}: {1}", data.Rows.IndexOf(row), e.Message), e); @@ -51,9 +52,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine columns.Contains(Fields.FuelConsumption); } - private static FuelConsumptionMap.FuelConsumptionEntry CreateFromColumnIndizes(DataRow row) + private static FuelConsumptionMap.Entry CreateFromColumnIndizes(DataRow row) { - return new FuelConsumptionMap.FuelConsumptionEntry( + return new FuelConsumptionMap.Entry( engineSpeed: row.ParseDouble(0).RPMtoRad(), torque: row.ParseDouble(1).SI<NewtonMeter>(), fuelConsumption: @@ -61,9 +62,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine ); } - private static FuelConsumptionMap.FuelConsumptionEntry CreateFromColumNames(DataRow row) + private static FuelConsumptionMap.Entry CreateFromColumNames(DataRow row) { - return new FuelConsumptionMap.FuelConsumptionEntry( + return new FuelConsumptionMap.Entry( engineSpeed: row.ParseDouble(Fields.EngineSpeed).SI().Rounds.Per.Minute.Cast<PerSecond>(), torque: row.ParseDouble(Fields.Torque).SI<NewtonMeter>(), fuelConsumption: diff --git a/VectoCore/VectoCore/Utils/DelaunayMap.cs b/VectoCore/VectoCore/Utils/DelaunayMap.cs index 5cc64203cbc07ccaf2770f9f34b63c45fb2648b4..fb9e42a5761548835c9cd482b4437093f31c8b09 100644 --- a/VectoCore/VectoCore/Utils/DelaunayMap.cs +++ b/VectoCore/VectoCore/Utils/DelaunayMap.cs @@ -35,6 +35,7 @@ using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Windows.Forms.DataVisualization.Charting; using TUGraz.VectoCommon.Exceptions; using TUGraz.VectoCommon.Models; @@ -46,7 +47,7 @@ namespace TUGraz.VectoCore.Utils public sealed class DelaunayMap : LoggingObject { internal ICollection<Point> Points = new HashSet<Point>(); - private List<Triangle> _triangles = new List<Triangle>(); + private List<Triangle> _triangles; private Edge[] _convexHull; private readonly string _mapName; @@ -213,6 +214,11 @@ namespace TUGraz.VectoCore.Utils } } + public double? Interpolate(SI x, SI y) + { + return Interpolate(x.Value(), y.Value()); + } + /// <summary> /// Interpolates the value of an point in the delaunay map. /// </summary> @@ -220,21 +226,35 @@ namespace TUGraz.VectoCore.Utils /// <param name="y"></param> /// <returns>a value if interpolation is successfull, /// null if interpolation has failed.</returns> + [MethodImpl(MethodImplOptions.Synchronized)] public double? Interpolate(double x, double y) { - if (!_triangles.Any()) + if (_triangles == null) throw new VectoException("Interpolation not possible. Call DelaunayMap.Triangulate first."); + x = (x - _minX) / (_maxX - _minX); y = (y - _minY) / (_maxY - _minY); - var tr = _triangles.Find(triangle => triangle.IsInside(x, y, exact: true)) ?? - _triangles.Find(triangle => triangle.IsInside(x, y, exact: false)); - if (tr != null) { - var plane = new Plane(tr); - return (plane.W - plane.X * x - plane.Y * y) / plane.Z; + var i = 0; + while (i < _triangles.Count && !_triangles[i].IsInside(x, y, true)) + i++; + if (i == _triangles.Count) { + i = 0; + while (i < _triangles.Count && !_triangles[i].IsInside(x, y, false)) + i++; } - return null; + if (i == _triangles.Count) + return null; + + var tr = _triangles[i]; + var plane = new Plane(tr); + return (plane.W - plane.X * x - plane.Y * y) / plane.Z; + } + + public double Extrapolate(SI x, SI y) + { + return Extrapolate(x.Value(), y.Value()); } /// <summary>