Skip to content

Commit 7172017

Browse files
committed
updateTrainPositions() when stopping train, go all the way to stop position.
It can happen that stopping point lays between current position and next tick position. Trains previously stoppet at their current position, so just before stop point. How much before depends on tick granularity and train speed, the bigger the tick step, the bigger the gap to stop point. Now instead when stop is requested, the exact amount left to travel is returned and a second custom tick routine is executed.
1 parent 359c7bf commit 7172017

2 files changed

Lines changed: 51 additions & 20 deletions

File tree

shared/src/traintastic/simulator/simulator.cpp

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -941,43 +941,60 @@ void Simulator::updateTrainPositions()
941941
trainState.speedOrDirectionChanged = false;
942942
}
943943

944-
auto updateHelper = [this](Simulator::Train::VehicleItem& item, float speed, bool reverse) -> bool
944+
auto updateHelper = [this](Simulator::Train::VehicleItem& item, float speed,
945+
bool reverse, float &outRemaining) -> bool
945946
{
946947
if(reverse)
947948
speed = -speed;
948949

949950
if(item.reversed == reverse)
950-
return updateVehiclePosition(item.vehicle->state.front, speed) &&
951-
updateVehiclePosition(item.vehicle->state.rear, speed);
951+
return updateVehiclePosition(item.vehicle->state.front, speed, outRemaining) &&
952+
updateVehiclePosition(item.vehicle->state.rear, speed, outRemaining);
952953
else
953-
return updateVehiclePosition(item.vehicle->state.rear, speed) &&
954-
updateVehiclePosition(item.vehicle->state.front, speed);
954+
return updateVehiclePosition(item.vehicle->state.rear, speed, outRemaining) &&
955+
updateVehiclePosition(item.vehicle->state.front, speed, outRemaining);
955956
};
956957

957958
const float speed = m_stateData.powerOn ? trainState.speed : 0.0f;
958959

959-
if(!trainState.reverse)
960+
float outRemaining = 0.0f;
961+
962+
do
960963
{
961-
for(auto& vehicleItem : train->vehicles)
964+
float tickPosDelta = speed;
965+
if(outRemaining > 0.0f && speed != 0.0f)
966+
{
967+
// This is second round, travel just remaining distance to stop
968+
if(speed > 0.0f)
969+
tickPosDelta = outRemaining;
970+
else
971+
tickPosDelta = outRemaining;
972+
}
973+
974+
if(!trainState.reverse)
962975
{
963-
if(!updateHelper(vehicleItem, speed, trainState.reverse))
976+
for(auto& vehicleItem : train->vehicles)
964977
{
965-
setTrainSpeed(train, 0.0f);
966-
break;
978+
if(!updateHelper(vehicleItem, tickPosDelta, trainState.reverse, outRemaining))
979+
{
980+
setTrainSpeed(train, 0.0f);
981+
break;
982+
}
967983
}
968984
}
969-
}
970-
else // reverse
971-
{
972-
for(auto& vehicleItem : train->vehicles | std::views::reverse)
985+
else // reverse
973986
{
974-
if(!updateHelper(vehicleItem, speed, trainState.reverse))
987+
for(auto& vehicleItem : train->vehicles | std::views::reverse)
975988
{
976-
setTrainSpeed(train, 0.0f);
977-
break;
989+
if(!updateHelper(vehicleItem, tickPosDelta, trainState.reverse, outRemaining))
990+
{
991+
setTrainSpeed(train, 0.0f);
992+
break;
993+
}
978994
}
979995
}
980996
}
997+
while(outRemaining > 0.0f && speed != 0.0f);
981998
}
982999
}
9831000

@@ -1004,8 +1021,10 @@ inline bool isTurnoutUnknownState(const Simulator::TrackSegment& segment,
10041021
return false;
10051022
}
10061023

1007-
bool Simulator::updateVehiclePosition(VehicleState::Face& face, const float speed)
1024+
bool Simulator::updateVehiclePosition(VehicleState::Face& face, const float speed, float &outRemaining)
10081025
{
1026+
outRemaining = 0.0f;
1027+
10091028
float distance = face.distance + (face.segmentDirectionInverted ? -speed : speed);
10101029

10111030
// Move to next segment when reaching the end:
@@ -1015,18 +1034,26 @@ bool Simulator::updateVehiclePosition(VehicleState::Face& face, const float spee
10151034
const auto& segment = staticData.trackSegments[face.segmentIndex];
10161035
const auto segmentLength = getSegmentLength(segment, m_stateData);
10171036

1018-
if(distance >= segmentLength)
1037+
// If train is right on the end of segment (distance == segmentLenght) do not update
1038+
// unlsess we are effectively moving. Because if speed is 0, segmentDirectionInverted is
1039+
// not calculated correctly and because in case of 2 segment touching by their side 1,
1040+
// it will infinitely jump vehicle face from one to another.
1041+
if(distance > segmentLength || (distance == segmentLength && speed != 0))
10191042
{
10201043
const auto nextSegmentIndex = getNextSegmentIndex(segment, true, m_stateData);
10211044
if(nextSegmentIndex == invalidIndex)
10221045
{
1046+
outRemaining = segmentLength - face.distance - 0.0001;
10231047
return false; // no next segment
10241048
}
10251049

10261050
auto& nextSegment = staticData.trackSegments[nextSegmentIndex];
10271051

10281052
if(isTurnoutUnknownState(nextSegment, m_stateData))
1053+
{
1054+
outRemaining = segmentLength - face.distance - 0.0001;
10291055
return false;
1056+
}
10301057

10311058
if(segment.sensor.index != invalidIndex)
10321059
{
@@ -1058,13 +1085,17 @@ bool Simulator::updateVehiclePosition(VehicleState::Face& face, const float spee
10581085
const auto nextSegmentIndex = getNextSegmentIndex(segment, false, m_stateData);
10591086
if(nextSegmentIndex == invalidIndex)
10601087
{
1088+
outRemaining = face.distance;
10611089
return false; // no next segment
10621090
}
10631091

10641092
auto& nextSegment = staticData.trackSegments[nextSegmentIndex];
10651093

10661094
if(isTurnoutUnknownState(nextSegment, m_stateData))
1095+
{
1096+
outRemaining = face.distance;
10671097
return false;
1098+
}
10681099

10691100
if(segment.sensor.index != invalidIndex)
10701101
{

shared/src/traintastic/simulator/simulator.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ class Simulator : public std::enable_shared_from_this<Simulator>
340340
void handShake();
341341

342342
void updateTrainPositions();
343-
bool updateVehiclePosition(VehicleState::Face& face, const float speed);
343+
bool updateVehiclePosition(VehicleState::Face& face, const float speed, float &outRemaining);
344344
void updateSensors();
345345

346346
bool isStraight(const TrackSegment& segment);

0 commit comments

Comments
 (0)