Skip to content

Commit

Permalink
Merge pull request #775 from Roeterdink/UpdateTurntablePools
Browse files Browse the repository at this point in the history
Update turntable pools
  • Loading branch information
cjakeman committed Feb 27, 2023
2 parents 1e52c2c + d84c8d8 commit be03e85
Showing 1 changed file with 63 additions and 47 deletions.
110 changes: 63 additions & 47 deletions Source/Orts.Simulation/Simulation/Timetables/TTTurntable.cs
Expand Up @@ -183,15 +183,20 @@ 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)
{
lastIndex = usedRoute.Count - 2;
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)
{
usedRoute.RemoveAt(usedRoute.Count - 1);
}

// create path list if required
if (AdditionalTurntableDetails.AccessPaths == null)
{
AdditionalTurntableDetails.AccessPaths = new List<AccessPathDetails>();
Expand Down Expand Up @@ -615,14 +620,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;
Expand Down Expand Up @@ -656,13 +653,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
Expand Down Expand Up @@ -847,7 +842,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;
Expand All @@ -864,24 +858,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--)
{
Expand Down Expand Up @@ -1007,7 +1004,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);
Expand All @@ -1023,7 +1020,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

Expand Down Expand Up @@ -1299,8 +1296,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);
Expand Down Expand Up @@ -1331,26 +1329,33 @@ 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);
}

// 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);
train.PoolStorageIndex = poolStorageIndex = reqPool;
}
}
return (newRoute);
}
Expand All @@ -1365,6 +1370,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);

Expand Down Expand Up @@ -2493,6 +2504,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)
Expand All @@ -2505,7 +2518,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;
}
}

Expand All @@ -2532,14 +2545,17 @@ 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;
trainOnTable = null;

// 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)
{
Expand Down Expand Up @@ -2586,4 +2602,4 @@ public bool TestTrainFormation (TTTrain parentTrain)
return (reqReverse);
}
}
}
}

0 comments on commit be03e85

Please sign in to comment.