From 104cd4fb441ef3f4dd63305d4cf3b8d2420054f8 Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <markus.quaritsch@tugraz.at> Date: Thu, 12 Nov 2020 18:24:35 +0100 Subject: [PATCH] adding missing files: gearshift position and shiftlineset (Effshift AT), formerly part of Voith shift strategy --- .../VectoCommon/Models/GearshiftPosition.cs | 188 ++++++++++++++++++ .../SimulationComponent/Impl/ShiftLineSet.cs | 71 +++++++ 2 files changed, 259 insertions(+) create mode 100644 VectoCommon/VectoCommon/Models/GearshiftPosition.cs create mode 100644 VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftLineSet.cs diff --git a/VectoCommon/VectoCommon/Models/GearshiftPosition.cs b/VectoCommon/VectoCommon/Models/GearshiftPosition.cs new file mode 100644 index 0000000000..d6a1efce27 --- /dev/null +++ b/VectoCommon/VectoCommon/Models/GearshiftPosition.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Security.Cryptography; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + [DebuggerDisplay("{Name}")] + public class GearshiftPosition + { + public uint Gear { get; } + public bool? TorqueConverterLocked { get; } + + public GearshiftPosition(uint gear, bool? torqueConverterLocked = null) + { + Gear = gear; + TorqueConverterLocked = torqueConverterLocked; + } + + public override string ToString() + { + return Name; + } + + public string Name + { + get { + return $"{Gear}{(Gear == 0 ? "" : (TorqueConverterLocked.HasValue ? (TorqueConverterLocked.Value ? "L" : "C") : ""))}"; + } + } + + public bool Engaged + { + get { return Gear != 0; } + } + + public override bool Equals(object x) + { + var other = x as GearshiftPosition; + if (other == null) + return false; + + return other.Gear == Gear && other.TorqueConverterLocked == TorqueConverterLocked; + } + + public override int GetHashCode() + { + return Name.GetHashCode(); + } + + public static bool operator >(GearshiftPosition p1, GearshiftPosition p2) + { + if (p1.Gear > p2.Gear) { + return true; + } + + if (p1.Gear != p2.Gear) { + return false; + } + + if (!p1.TorqueConverterLocked.HasValue || !p2.TorqueConverterLocked.HasValue) { + return false; + } + + return p1.TorqueConverterLocked.Value && !p2.TorqueConverterLocked.Value; + } + + public static bool operator <(GearshiftPosition p1, GearshiftPosition p2) + { + if (p1.Gear < p2.Gear) { + return true; + } + + if (p1.Gear != p2.Gear) { + return false; + } + + if (!p1.TorqueConverterLocked.HasValue || !p2.TorqueConverterLocked.HasValue) { + return false; + } + + return p2.TorqueConverterLocked.Value && !p1.TorqueConverterLocked.Value; + } + + + } + + public class GearList :IEnumerable<GearshiftPosition> + { + protected GearshiftPosition[] Entries; + + public GearList(GearshiftPosition[] gearList) + { + Entries = gearList; + } + + public bool HasPredecessor(GearshiftPosition cur) + { + var idx = Array.IndexOf(Entries, cur); + return idx > 0; + } + + + public GearshiftPosition Predecessor(GearshiftPosition cur) + { + var idx = Array.IndexOf(Entries, cur); + + return idx <= 0 ? null : Entries[idx - 1]; + } + + public bool HasSuccessor(GearshiftPosition cur) + { + var idx = Array.IndexOf(Entries, cur); + return idx < Entries.Length - 1; + } + + public GearshiftPosition Successor(GearshiftPosition cur) + { + var idx = Array.IndexOf(Entries, cur); + + return idx < 0 || idx >= Entries.Length - 1 ? null : Entries[idx + 1]; + } + + public GearshiftPosition Successor(GearshiftPosition cur, uint numUp) + { + var idx = Array.IndexOf(Entries, cur); + + if (idx < 0) { + return null; + } + + var next = idx + numUp; + + return next >= Entries.Length ? Entries.Last() : Entries[next]; + } + + public GearshiftPosition Predecessor(GearshiftPosition cur, uint numDown) + { + var idx = Array.IndexOf(Entries, cur); + + if (idx < 0) { + return null; + } + + var next = idx - numDown; + + return next < 0 ? Entries.First() : Entries[next]; + } + + public IEnumerator<GearshiftPosition> GetEnumerator() + { + foreach (var entry in Entries) { + yield return entry; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public int Distance(GearshiftPosition from, GearshiftPosition to) + { + var startIdx = Array.IndexOf(Entries, from); + var endIdx = Array.IndexOf(Entries, to); + return startIdx - endIdx; + } + + + public IEnumerable<GearshiftPosition> IterateGears(GearshiftPosition from, GearshiftPosition to) + { + var startIdx = Array.IndexOf(Entries, from); + var endIdx = Array.IndexOf(Entries, to); + + if (endIdx > startIdx) { + for (var i = startIdx; i <= endIdx; i++) { + yield return Entries[i]; + } + } else { + for (var i = startIdx; i >= endIdx; i--) { + yield return Entries[i]; + } + } + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftLineSet.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftLineSet.cs new file mode 100644 index 0000000000..1d14796f0d --- /dev/null +++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftLineSet.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.Models.SimulationComponent.Impl +{ + public class ShiftLineSet + { + public const double DownhillSlope = -5; + public const double UphillSlope = 5; + + public Dictionary<int, ShiftLines> LoadStages = new Dictionary<int, ShiftLines>(); + + public PerSecond LookupShiftSpeed( + int loadStage, Radian gradient, MeterPerSquareSecond acceleration, MeterPerSquareSecond aMin, + MeterPerSquareSecond aMax) + { + if (!LoadStages.ContainsKey(loadStage)) { + throw new VectoException("No Shiftlines for load stage {0} found", loadStage); + } + + var shiftLinesSet = LoadStages[loadStage]; + + //var slope = (Math.Tan(gradient.Value()) * 100).LimitTo( + // ATShiftStrategyVoith.DownhillSlope, ATShiftStrategyVoith.UphillSlope); + + gradient = gradient.LimitTo( + VectoMath.InclinationToAngle(DownhillSlope), + VectoMath.InclinationToAngle(UphillSlope)); + var shiftLine = shiftLinesSet.LookupShiftSpeed(gradient); + var acc = aMin > aMax ? acceleration.LimitTo(aMax, aMin) : acceleration.LimitTo(aMin, aMax); + + var shiftSpeed = VectoMath.Interpolate( + aMin, aMax, shiftLine.ShiftSpeedAMin, shiftLine.ShiftSpeedAMax, acc); + + return shiftSpeed; + } + } + + public class ShiftLines + { + + internal readonly List<Tuple<Radian, PerSecond>> entriesAMin = new List<Tuple<Radian, PerSecond>>(); + internal readonly List<Tuple<Radian, PerSecond>> entriesAMax = new List<Tuple<Radian, PerSecond>>(); + + + public ShiftSpeedTuple LookupShiftSpeed(Radian gradent) + { + var sectLow = entriesAMin.GetSection(x => x.Item1 < gradent); + var sectHigh = entriesAMax.GetSection(x => x.Item1 < gradent); + + return new ShiftSpeedTuple( + VectoMath.Interpolate(sectLow.Item1.Item1, sectLow.Item2.Item1, sectLow.Item1.Item2, sectLow.Item2.Item2, gradent), + VectoMath.Interpolate( + sectHigh.Item1.Item1, sectHigh.Item2.Item1, sectHigh.Item1.Item2, sectHigh.Item2.Item2, gradent)); + } + } + + public class ShiftSpeedTuple + { + public PerSecond ShiftSpeedAMin { get; } + public PerSecond ShiftSpeedAMax { get; } + + public ShiftSpeedTuple(PerSecond shiftSpeedAMin, PerSecond shiftSpeedAMax) + { + ShiftSpeedAMin = shiftSpeedAMin; + ShiftSpeedAMax = shiftSpeedAMax; + } + } +} \ No newline at end of file -- GitLab