diff --git a/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs b/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs index d42b0e84d088c36beaababb164f0dc994a212fcd..d79a2b112290277d903faeb73ee393c1338afecc 100644 --- a/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs +++ b/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using Newtonsoft.Json; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine; @@ -58,6 +59,31 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data [JsonProperty(Required = Required.Always)] public double FileVersion; + + protected bool Equals(DataHeader other) + { + return string.Equals(CreatedBy, other.CreatedBy) && Date.Equals(other.Date) && string.Equals(AppVersion, other.AppVersion) && FileVersion.Equals(other.FileVersion); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((DataHeader) obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = (CreatedBy != null ? CreatedBy.GetHashCode() : 0); + hashCode = (hashCode*397) ^ Date.GetHashCode(); + hashCode = (hashCode*397) ^ (AppVersion != null ? AppVersion.GetHashCode() : 0); + hashCode = (hashCode*397) ^ FileVersion.GetHashCode(); + return hashCode; + } + } } [JsonProperty(Required = Required.Always)] @@ -87,6 +113,27 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data [JsonProperty(Required = Required.Always)] public string Gears; + + protected bool Equals(DataFullLoadCurve other) + { + return string.Equals(Path, other.Path) && string.Equals(Gears, other.Gears); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((DataFullLoadCurve) obj); + } + + public override int GetHashCode() + { + unchecked + { + return ((Path != null ? Path.GetHashCode() : 0)*397) ^ (Gears != null ? Gears.GetHashCode() : 0); + } + } } [JsonProperty(Required = Required.Always)] @@ -103,16 +150,80 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data [JsonProperty("WHTC-Motorway")] public double WHTCMotorway; + + protected bool Equals(DataBody other) + { + return SavedInDeclarationMode.Equals(other.SavedInDeclarationMode) + && string.Equals(ModelName, other.ModelName) + && Displacement.Equals(other.Displacement) + && IdleSpeed.Equals(other.IdleSpeed) + && Inertia.Equals(other.Inertia) + && FullLoadCurves.SequenceEqual(other.FullLoadCurves) + && string.Equals(FuelMap, other.FuelMap) + && WHTCUrban.Equals(other.WHTCUrban) + && WHTCRural.Equals(other.WHTCRural) + && WHTCMotorway.Equals(other.WHTCMotorway); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((DataBody)obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = SavedInDeclarationMode.GetHashCode(); + hashCode = (hashCode * 397) ^ (ModelName != null ? ModelName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ Displacement.GetHashCode(); + hashCode = (hashCode * 397) ^ IdleSpeed.GetHashCode(); + hashCode = (hashCode * 397) ^ Inertia.GetHashCode(); + hashCode = (hashCode * 397) ^ (FullLoadCurves != null ? FullLoadCurves.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (FuelMap != null ? FuelMap.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ WHTCUrban.GetHashCode(); + hashCode = (hashCode * 397) ^ WHTCRural.GetHashCode(); + hashCode = (hashCode * 397) ^ WHTCMotorway.GetHashCode(); + return hashCode; + } + } } [JsonProperty(Required = Required.Always)] public DataBody Body; + + protected bool Equals(Data other) + { + return Equals(Header, other.Header) && Equals(Body, other.Body); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((Data) obj); + } + + public override int GetHashCode() + { + unchecked + { + return ((Header != null ? Header.GetHashCode() : 0)*397) ^ (Body != null ? Body.GetHashCode() : 0); + } + } } + private Data _data; + protected bool Equals(CombustionEngineData other) { - return Equals(_data, other._data) - && Equals(_fullLoadCurves, other._fullLoadCurves) + return Equals(_data, other._data) + && _fullLoadCurves.Keys.SequenceEqual(other._fullLoadCurves.Keys) + && _fullLoadCurves.Values.SequenceEqual(other._fullLoadCurves.Values) && Equals(ConsumptionMap, other.ConsumptionMap); } @@ -121,22 +232,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; - return Equals((CombustionEngineData) obj); + return Equals((CombustionEngineData)obj); } public override int GetHashCode() { unchecked { - var hashCode = (_data != null ? _data.GetHashCode() : 0); - hashCode = (hashCode*397) ^ (_fullLoadCurves != null ? _fullLoadCurves.GetHashCode() : 0); - hashCode = (hashCode*397) ^ (ConsumptionMap != null ? ConsumptionMap.GetHashCode() : 0); + var hashCode = _data.GetHashCode(); + hashCode = (hashCode * 397) ^ (_fullLoadCurves != null ? _fullLoadCurves.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (ConsumptionMap != null ? ConsumptionMap.GetHashCode() : 0); return hashCode; } } - private Data _data; - public bool SavedInDeclarationMode { get { return _data.Body.SavedInDeclarationMode; } @@ -234,7 +343,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data public FullLoadCurve GetFullLoadCurve(uint gear) { - // TODO: @@@quam refactor + // TODO: @@@quam refactor foreach (var gearRange in _fullLoadCurves.Keys) { var low = uint.Parse(gearRange.Split('-').First().Trim()); diff --git a/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs b/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs index 1ccc576429ce2f08858fb0aa7b97232c0a2c5e1c..e0fad87e0c43472753661f57f861976b64e08c82 100644 --- a/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs +++ b/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Linq; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Utils; @@ -27,7 +28,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine protected bool Equals(FuelConsumptionMap other) { - return Equals(_entries, other._entries) && Equals(_fuelMap, other._fuelMap); + return _entries.SequenceEqual(other._entries) + && Equals(_fuelMap, other._fuelMap); } public override bool Equals(object obj) @@ -46,15 +48,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine } } - private class FuelConsumptionEntry + private struct FuelConsumptionEntry { public double EngineSpeed { get; set; } public double Torque { get; set; } public double FuelConsumption { get; set; } } - private IList<FuelConsumptionEntry> _entries = new List<FuelConsumptionEntry>(); - private DelauneyMap _fuelMap = new DelauneyMap(); + private readonly IList<FuelConsumptionEntry> _entries = new List<FuelConsumptionEntry>(); + private readonly DelauneyMap _fuelMap = new DelauneyMap(); private FuelConsumptionMap() { } diff --git a/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs b/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs index 3e5778e3a920f711554f63469d91fa6ccc8bc122..8a3a6cf556d2015a1678a9ed9a16fd8e3a8f5321 100644 --- a/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs +++ b/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Data; +using System.Linq; using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine @@ -27,7 +28,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine protected bool Equals(FullLoadCurve other) { - return Equals(entries, other.entries); + return _entries.SequenceEqual(other._entries); } public override bool Equals(object obj) @@ -40,7 +41,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine public override int GetHashCode() { - return (entries != null ? entries.GetHashCode() : 0); + return (_entries != null ? _entries.GetHashCode() : 0); } private class FullLoadCurveEntry @@ -49,15 +50,43 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine public double TorqueFullLoad { get; set; } public double TorqueDrag { get; set; } public double PT1 { get; set; } + + protected bool Equals(FullLoadCurveEntry other) + { + return EngineSpeed.Equals(other.EngineSpeed) + && TorqueFullLoad.Equals(other.TorqueFullLoad) + && TorqueDrag.Equals(other.TorqueDrag) + && PT1.Equals(other.PT1); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((FullLoadCurveEntry) obj); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = EngineSpeed.GetHashCode(); + hashCode = (hashCode*397) ^ TorqueFullLoad.GetHashCode(); + hashCode = (hashCode*397) ^ TorqueDrag.GetHashCode(); + hashCode = (hashCode*397) ^ PT1.GetHashCode(); + return hashCode; + } + } } - private List<FullLoadCurveEntry> entries; + private List<FullLoadCurveEntry> _entries; public static FullLoadCurve ReadFromFile(string fileName) { var fullLoadCurve = new FullLoadCurve(); var data = VectoCSVFile.Read(fileName); - fullLoadCurve.entries = new List<FullLoadCurveEntry>(); + fullLoadCurve._entries = new List<FullLoadCurveEntry>(); //todo: catch exceptions if value format is wrong. foreach (DataRow row in data.Rows) @@ -67,7 +96,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine entry.TorqueFullLoad = row.GetDouble(Fields.TorqueFullLoad); entry.TorqueDrag = row.GetDouble(Fields.TorqueDrag); entry.PT1 = row.GetDouble(Fields.PT1); - fullLoadCurve.entries.Add(entry); + fullLoadCurve._entries.Add(entry); } return fullLoadCurve; } @@ -75,8 +104,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine public double FullLoadStationaryTorque(double rpm) { var idx = FindIndexForRpm(rpm); - return VectoMath.Interpolate(entries[idx - 1].EngineSpeed, entries[idx].EngineSpeed, - entries[idx - 1].TorqueFullLoad, entries[idx].TorqueFullLoad, rpm); + return VectoMath.Interpolate(_entries[idx - 1].EngineSpeed, _entries[idx].EngineSpeed, + _entries[idx - 1].TorqueFullLoad, _entries[idx].TorqueFullLoad, rpm); } public double FullLoadStationaryPower(double rpm) @@ -87,8 +116,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine public double DragLoadStationaryTorque(double rpm) { var idx = FindIndexForRpm(rpm); - return VectoMath.Interpolate(entries[idx - 1].EngineSpeed, entries[idx].EngineSpeed, - entries[idx - 1].TorqueDrag, entries[idx].TorqueDrag, rpm); + return VectoMath.Interpolate(_entries[idx - 1].EngineSpeed, _entries[idx].EngineSpeed, + _entries[idx - 1].TorqueDrag, _entries[idx].TorqueDrag, rpm); } public double DragLoadStationaryPower(double rpm) @@ -99,22 +128,22 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine public double PT1(double rpm) { var idx = FindIndexForRpm(rpm); - return VectoMath.Interpolate(entries[idx - 1].EngineSpeed, entries[idx].EngineSpeed, - entries[idx - 1].PT1, entries[idx].PT1, rpm); + return VectoMath.Interpolate(_entries[idx - 1].EngineSpeed, _entries[idx].EngineSpeed, + _entries[idx - 1].PT1, _entries[idx].PT1, rpm); } protected int FindIndexForRpm(double rpm) { int idx; - if (rpm < entries[0].EngineSpeed) { + if (rpm < _entries[0].EngineSpeed) { Log.ErrorFormat("requested rpm below minimum rpm in FLD curve - extrapolating. n: {0}, rpm_min: {1}", rpm, - entries[0].EngineSpeed); + _entries[0].EngineSpeed); idx = 1; } else { - idx = entries.FindIndex(x => x.EngineSpeed > rpm); + idx = _entries.FindIndex(x => x.EngineSpeed > rpm); } if (idx <= 0) { - idx = rpm > entries[0].EngineSpeed ? entries.Count - 1 : 1; + idx = rpm > _entries[0].EngineSpeed ? _entries.Count - 1 : 1; } return idx; } diff --git a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs index dda5c13d4f5aaf744619e555f88cc8b665468951..239a79fa096ffd90104457aac6f48803b8ff1392 100644 --- a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs +++ b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using TUGraz.VectoCore.Exceptions; using TUGraz.VectoCore.Models.Connector.Ports; using TUGraz.VectoCore.Models.Simulation.Data; @@ -37,7 +38,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl protected bool Equals(EngineState other) { - return OperationMode == other.OperationMode && EnginePower.Equals(other.EnginePower) && EngineSpeed.Equals(other.EngineSpeed) && EnginePowerLoss.Equals(other.EnginePowerLoss) && AbsTime.Equals(other.AbsTime); + return OperationMode == other.OperationMode + && EnginePower.Equals(other.EnginePower) + && EngineSpeed.Equals(other.EngineSpeed) + && EnginePowerLoss.Equals(other.EnginePowerLoss) + && AbsTime.Equals(other.AbsTime); } public override bool Equals(object obj) @@ -87,7 +92,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl return Equals(_data, other._data) && Equals(_previousState, other._previousState) && Equals(_currentState, other._currentState) - && Equals(_enginePowerCorrections, other._enginePowerCorrections); + && _enginePowerCorrections.SequenceEqual(other._enginePowerCorrections); } public override bool Equals(object obj) diff --git a/VectoCore/Models/SimulationComponent/VectoSimulationComponent.cs b/VectoCore/Models/SimulationComponent/VectoSimulationComponent.cs index ba1b7d06f733f716b3f54fd34b1a0fdca47e3dfd..525a96ed7a6a916bd133554ac111f8d2fd6ef55b 100644 --- a/VectoCore/Models/SimulationComponent/VectoSimulationComponent.cs +++ b/VectoCore/Models/SimulationComponent/VectoSimulationComponent.cs @@ -33,7 +33,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent { const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; var props = type.GetFields(flags).Select(f => CreateProperty(f, memberSerialization)).ToList(); - //props.ForEach(p => { p.Writable = true; p.Readable = true; }); + props.ForEach(p => { p.Writable = true; p.Readable = true; }); return props; } } @@ -48,7 +48,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent { try { - return JsonConvert.DeserializeObject<T>(data); + var settings = new JsonSerializerSettings { ContractResolver = new MyContractResolver() }; + return JsonConvert.DeserializeObject<T>(data, settings); } catch (Exception e) { diff --git a/VectoCore/Utils/DelauneyMap.cs b/VectoCore/Utils/DelauneyMap.cs index b03af31392ab985a704180964ffa732860744d17..9c4738dab44d2defde37c2e0e29d8dd553861e4d 100644 --- a/VectoCore/Utils/DelauneyMap.cs +++ b/VectoCore/Utils/DelauneyMap.cs @@ -17,7 +17,8 @@ namespace TUGraz.VectoCore.Utils protected bool Equals(DelauneyMap other) { - return Equals(_points, other._points) && Equals(_triangles, other._triangles); + return _points.SequenceEqual(other._points) + && _triangles.SequenceEqual(other._triangles); } public override bool Equals(object obj) diff --git a/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs b/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs index a757fe926ce6400200279eaa40ee234a2687d3cc..f65c85568bca09b5f82727bef2fd6937b69cb2df 100644 --- a/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs +++ b/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs @@ -2,7 +2,6 @@ using System.IO; using System.Reflection; using Microsoft.VisualStudio.TestTools.UnitTesting; -using Newtonsoft.Json; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent; using TUGraz.VectoCore.Models.SimulationComponent.Data;