From 1852fcbf6b4afdd6d05a16f66435042b3c54db5c Mon Sep 17 00:00:00 2001 From: roeter Date: Sat, 21 Jan 2023 13:50:50 +0100 Subject: [PATCH 1/2] Update turntable pools --- .../Simulation/Timetables/TTTurntable.cs | 102 +++++++++++------- 1 file changed, 64 insertions(+), 38 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/Timetables/TTTurntable.cs b/Source/Orts.Simulation/Simulation/Timetables/TTTurntable.cs index b44207df59..4d1d9a52b3 100644 --- a/Source/Orts.Simulation/Simulation/Timetables/TTTurntable.cs +++ b/Source/Orts.Simulation/Simulation/Timetables/TTTurntable.cs @@ -183,15 +183,21 @@ public TimetableTurntablePool(TimetableReader fileContents, ref int lineindex, S if (pathValid) { Train.TCRoutePath fullRoute = new Train.TCRoutePath(newPath, -2, 1, Simulatorref.Signals, -1, Simulatorref.Settings); - // if last element is end of track, remove it from path + + // if first element is end of track, remove it from path (path is defined outbound) Train.TCSubpathRoute usedRoute = fullRoute.TCRouteSubpaths[0]; - int lastIndex = usedRoute.Count - 1; - int lastSectionIndex = usedRoute[lastIndex].TCSectionIndex; - if (Simulatorref.Signals.TrackCircuitList[lastSectionIndex].CircuitType == TrackCircuitSection.TrackCircuitType.EndOfTrack) + if (Simulatorref.Signals.TrackCircuitList[usedRoute.First().TCSectionIndex].CircuitType == TrackCircuitSection.TrackCircuitType.EndOfTrack) + { + usedRoute.RemoveAt(0); + } + + // if last element is send of track, remove it from path (if path has no junction it may be in reverse direction) + if (Simulatorref.Signals.TrackCircuitList[usedRoute.Last().TCSectionIndex].CircuitType == TrackCircuitSection.TrackCircuitType.EndOfTrack) { - lastIndex = usedRoute.Count - 2; + usedRoute.RemoveAt(usedRoute.Count - 1); } + // create path list if required if (AdditionalTurntableDetails.AccessPaths == null) { AdditionalTurntableDetails.AccessPaths = new List(); @@ -615,14 +621,6 @@ private void CalculateAccessOffsets(int ipath, Turntable thisTurntable) { AccessPathDetails thisPath = AdditionalTurntableDetails.AccessPaths[ipath]; - float baseLength = 0; - - // calculate total length of path sections except first section - for (int isection = 1; isection < thisPath.AccessPath.Count; isection++) - { - baseLength += Simulatorref.Signals.TrackCircuitList[thisPath.AccessPath[isection].TCSectionIndex].Length; - } - // calculate total length of track sections in first section backward upto turntable section TrackCircuitSection thisSection = Simulatorref.Signals.TrackCircuitList[thisPath.AccessPath[0].TCSectionIndex]; int trackNodeIndex = thisSection.OriginalIndex; @@ -656,13 +654,11 @@ private void CalculateAccessOffsets(int ipath, Turntable thisTurntable) thisPath.AccessTraveller.Direction = Traveller.TravellerDirection.Backward; } - float totalLength = baseLength + entrySectionLength; - // deduct clearance for turntable // if no explicit clearance defined, use length of last vector before turntable - thisPath.TableApproachOffset = totalLength - AdditionalTurntableDetails.TurntableApproachClearanceM; - thisPath.TableMiddleEntry = totalLength + (thisTurntable.Length / 2.0f); + thisPath.TableApproachOffset = entrySectionLength - AdditionalTurntableDetails.TurntableApproachClearanceM; + thisPath.TableMiddleEntry = entrySectionLength + (thisTurntable.Length / 2.0f); thisPath.TableMiddleExit = exitSectionLength + (thisTurntable.Length / 2.0f); #if DEBUG_TURNTABLEINFO @@ -847,7 +843,6 @@ public override bool TestPoolExit(TTTrain train) bool validPath = TestPoolAccess(train, out testAccess); return (validPath); } - public bool TestPoolAccess(TTTrain train, out int accessIndex) { bool validPool = false; @@ -864,24 +859,27 @@ public bool TestPoolAccess(TTTrain train, out int accessIndex) for (int iSection = train.TCRoute.TCRouteSubpaths.Last().Count - 1; iSection >= 0 && reqPath == -1; iSection--) { int lastSectionIndex = train.TCRoute.TCRouteSubpaths.Last()[iSection].TCSectionIndex; - int lastSectionDirection = train.TCRoute.TCRouteSubpaths.Last().Last().Direction; + int lastSectionDirection = train.TCRoute.TCRouteSubpaths.Last()[iSection].Direction; - for (int iPath = 0; iPath < AdditionalTurntableDetails.AccessPaths.Count && reqPath < 0; iPath++) + if (train.signalRef.TrackCircuitList[lastSectionIndex].CircuitType == TrackCircuitSection.TrackCircuitType.Normal) { - Train.TCSubpathRoute accessPath = AdditionalTurntableDetails.AccessPaths[iPath].AccessPath; - reqPathIndex = accessPath.GetRouteIndex(lastSectionIndex, 0); - - // path is defined outbound, so directions must be opposite - if (reqPathIndex >= 0 && accessPath[reqPathIndex].Direction != lastSectionDirection) + for (int iPath = 0; iPath < AdditionalTurntableDetails.AccessPaths.Count && reqPath < 0; iPath++) { - reqPath = iPath; - lastValidSectionIndex = iSection; + Train.TCSubpathRoute accessPath = AdditionalTurntableDetails.AccessPaths[iPath].AccessPath; + reqPathIndex = accessPath.GetRouteIndex(lastSectionIndex, 0); + + // path is defined outbound, so directions must be opposite + if (reqPathIndex >= 0 && accessPath[reqPathIndex].Direction != lastSectionDirection) + { + reqPath = iPath; + lastValidSectionIndex = iSection; + } } } } // remove sections from train route if required - if (lastValidSectionIndex < train.TCRoute.TCRouteSubpaths.Last().Count - 1) + if (reqPath >= 0 && lastValidSectionIndex < train.TCRoute.TCRouteSubpaths.Last().Count - 1) { for (int iSection = train.TCRoute.TCRouteSubpaths.Last().Count - 1; iSection > lastValidSectionIndex; iSection--) { @@ -1007,7 +1005,7 @@ override public TrainFromPool ExtractTrain(ref TTTrain train, int presentTime) #if DEBUG_POOLINFO sob = new StringBuilder(); sob.AppendFormat("Pool {0} : cannot find train {1} for {2} ({3}) \n", PoolName, selectedTrainNumber, train.Number, train.Name); - sob.AppendFormat(" stored units : {0}", reqStorage.StoredUnits.Count); + sob.AppendFormat(" stored units : {0}", StoragePool[selectedStorage].StoredUnits.Count); File.AppendAllText(@"C:\temp\PoolAnal.csv", sob.ToString() + "\n"); #endif return (TrainFromPool.Delayed); @@ -1023,7 +1021,7 @@ override public TrainFromPool ExtractTrain(ref TTTrain train, int presentTime) #if DEBUG_POOLINFO sob = new StringBuilder(); sob.AppendFormat("Pool {0} : train {1} ({2}) extracted as {3} ({4}) \n", PoolName, selectedTrain.Number, selectedTrain.Name, train.Number, train.Name); - sob.AppendFormat(" stored units : {0}", reqStorage.StoredUnits.Count); + sob.AppendFormat(" stored units : {0}", StoragePool[selectedStorage].StoredUnits.Count); File.AppendAllText(@"C:\temp\PoolAnal.csv", sob.ToString() + "\n"); #endif @@ -1299,8 +1297,9 @@ override public Train.TCSubpathRoute SetPoolExit(TTTrain train, out int poolStor // no action if state is poolClaimed - state will resolve as train ahead is stabled in pool // valid pool - else if (reqPool > 0) + else if (reqPool >= 0) { + // train approaches from exit path - train is moving toward turntable and is stored after turntable movement if (checkAccessPath) { bool validPath = TestPoolAccess(train, out reqPath); @@ -1331,16 +1330,32 @@ override public Train.TCSubpathRoute SetPoolExit(TTTrain train, out int poolStor } } - poolStorageIndex = reqPool; + train.PoolStorageIndex = poolStorageIndex = reqPool; + + // set approach to turntable + // also add unit to storage as claim + newRoute.Last().MovingTableApproachPath = reqPath; + AddUnit(train, true); + StoragePool[poolStorageIndex].ClaimUnits.Add(train.Number); } } + // create new route from access track only // use first defined access track - // reverse path as path is outbound + // if only one unit allowed on storage, reverse path so train stands at allocated position + // if multiple units allowed on storage, do not reverse path so train moves to end of storage location else { - newRoute = new Train.TCSubpathRoute(AdditionalTurntableDetails.AccessPaths[0].AccessPath.ReversePath(train.signalRef)); - poolStorageIndex = reqPool; + if (StoragePool[poolStorageIndex].maxStoredUnits == 1) + { + newRoute = new Train.TCSubpathRoute(AdditionalTurntableDetails.AccessPaths[0].AccessPath.ReversePath(train.signalRef)); + } + else + { + newRoute = new Train.TCSubpathRoute(AdditionalTurntableDetails.AccessPaths[0].AccessPath); + } + + train.PoolStorageIndex = poolStorageIndex = reqPool; } } @@ -1365,6 +1380,12 @@ override public float GetEndOfRouteDistance(Train.TCSubpathRoute thisRoute, Trai // get distance to approach point from present position of train int turntableSectionIndex = thisRoute.GetRouteIndex(AdditionalTurntableDetails.AccessPaths[pathIndex].AccessPath[0].TCSectionIndex, 0); float startoffset = signalRef.TrackCircuitList[frontPosition.TCSectionIndex].Length - frontPosition.TCOffset; + if (frontPosition.RouteListIndex < 0 && turntableSectionIndex < 0) + { + Trace.TraceInformation("Invalid check on turntable approach : present position and turntable index both < 0; for pool : " + PoolName); + return (-1); + } + float distanceToTurntable = thisRoute.GetDistanceAlongRoute(frontPosition.RouteListIndex, startoffset, turntableSectionIndex, AdditionalTurntableDetails.AccessPaths[pathIndex].TableApproachOffset, true, signalRef); @@ -2493,6 +2514,8 @@ public void PrepareMoveOffTable() parentTrain.ControlMode = Train.TRAIN_CONTROL.AUTO_NODE; parentTrain.DistanceTravelledM = 0; parentTrain.DelayedStartMoving(AITrain.AI_START_MOVEMENT.PATH_ACTION); + parentTrain.EndAuthorityType[0] = Train.END_AUTHORITY.NO_PATH_RESERVED; + parentTrain.EndAuthorityType[1] = Train.END_AUTHORITY.NO_PATH_RESERVED; // actions for mode access (train going into storage) if (MovingTableAction == MovingTableActionEnum.FromAccess) @@ -2505,7 +2528,7 @@ public void PrepareMoveOffTable() float endOffset = parentPool.StoragePool[StoragePathIndex].StoragePathTraveller.TrackNodeOffset + parentTrain.Length; if (endOffset < parentTrain.DistanceToEndNodeAuthorityM[0]) { - parentTrain.DistanceToEndNodeAuthorityM[0] = endOffset; + parentTrain.DistanceToEndNodeAuthorityM[0] = parentTrain.NextStopDistanceM = endOffset; } } @@ -2532,6 +2555,9 @@ public void PrepareMoveOffTable() public void RemoveTrainFromTurntable() { // clear table + + if (parentTurntable == null) parentTurntable = parentPool.Simulatorref.MovingTables[parentIndex] as Turntable; + parentTurntable.TrainsOnMovingTable.Clear(); parentTurntable.InUse = false; parentTurntable.GoToAutoTarget = false; @@ -2539,7 +2565,7 @@ public void RemoveTrainFromTurntable() // reset train speed parentTrain.TrainMaxSpeedMpS = originalTrainMaxSpeedMpS; - Train.ActivateSpeedLimit activeSpeeds = new Train.ActivateSpeedLimit(0.0f, originalSpeedLimitMpS, originalSpeedSignalMpS); + Train.ActivateSpeedLimit activeSpeeds = new Train.ActivateSpeedLimit(0.0f, originalSpeedLimitMpS, originalSpeedSignalMpS, originalSpeedLimitMpS); if (parentTrain.TrainType == Train.TRAINTYPE.PLAYER) { @@ -2586,4 +2612,4 @@ public bool TestTrainFormation (TTTrain parentTrain) return (reqReverse); } } -} \ No newline at end of file +} From d84c8d879d6942b63e87edeca9e9e4b45640828b Mon Sep 17 00:00:00 2001 From: roeter Date: Sat, 21 Jan 2023 13:58:22 +0100 Subject: [PATCH 2/2] Update Turntable Pools --- .../Simulation/Timetables/TTTurntable.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/Timetables/TTTurntable.cs b/Source/Orts.Simulation/Simulation/Timetables/TTTurntable.cs index 4d1d9a52b3..5cdaf887af 100644 --- a/Source/Orts.Simulation/Simulation/Timetables/TTTurntable.cs +++ b/Source/Orts.Simulation/Simulation/Timetables/TTTurntable.cs @@ -183,7 +183,6 @@ public TimetableTurntablePool(TimetableReader fileContents, ref int lineindex, S if (pathValid) { Train.TCRoutePath fullRoute = new Train.TCRoutePath(newPath, -2, 1, Simulatorref.Signals, -1, Simulatorref.Settings); - // if first element is end of track, remove it from path (path is defined outbound) Train.TCSubpathRoute usedRoute = fullRoute.TCRouteSubpaths[0]; if (Simulatorref.Signals.TrackCircuitList[usedRoute.First().TCSectionIndex].CircuitType == TrackCircuitSection.TrackCircuitType.EndOfTrack) @@ -1358,15 +1357,6 @@ override public Train.TCSubpathRoute SetPoolExit(TTTrain train, out int poolStor train.PoolStorageIndex = poolStorageIndex = reqPool; } } - - // if route is valid, set state for last section to approach moving table - // also add unit to storage as claim - if (newRoute != null) - { - newRoute.Last().MovingTableApproachPath = reqPath; - AddUnit(train, true); - StoragePool[poolStorageIndex].ClaimUnits.Add(train.Number); - } return (newRoute); }