@@ -560,10 +560,17 @@ void Simulator::applyTrainSpeedDelta(Train *train, float delta)
560560 std::lock_guard<std::recursive_mutex> lock (m_stateMutex);
561561
562562 const float speed = std::clamp (train->state .speed + delta, 0 .0f , train->speedMax );
563- if (train->state .speed != speed)
563+ setTrainSpeed (train, speed);
564+ }
565+
566+ void Simulator::setTrainMode (Train *train, TrainState::Mode m)
567+ {
568+ std::lock_guard<std::recursive_mutex> lock (m_stateMutex);
569+
570+ if (train->state .mode != m)
564571 {
565- train->state .speed = speed ;
566- train->state .speedOrDirectionChanged = true ;
572+ train->state .mode = m ;
573+ train->state .nextSignalDirty = true ;
567574 }
568575}
569576
@@ -573,11 +580,8 @@ void Simulator::stopAllTrains()
573580 for (auto & it : m_stateData.trains )
574581 {
575582 auto *train = it.second ;
576- if (train->state .speed != 0 .0f )
577- {
578- train->state .speed = 0 .0f ;
579- train->state .speedOrDirectionChanged = true ;
580- }
583+ setTrainSpeed (train, 0 .0f );
584+ setTrainMode (train, TrainState::Mode::Manual);
581585 }
582586}
583587
@@ -725,8 +729,8 @@ void Simulator::receive(const SimulatorProtocol::Message& message, size_t fromCo
725729 auto &trainState = train->state ;
726730 if (trainState.speed != speed || trainState.reverse != reverse)
727731 {
728- trainState. speed = speed;
729- trainState. reverse = reverse;
732+ setTrainSpeed (train, speed) ;
733+ setTrainDirection (train, reverse) ;
730734 }
731735 break ;
732736 }
@@ -1000,17 +1004,17 @@ void Simulator::updateTrainPositions()
10001004
10011005 auto updateHelper = [this ](Simulator::Train::VehicleItem& item, float speed,
10021006 bool reverse, bool isFirst,
1003- TrainState &trainState_ ) -> bool
1007+ Train &train_ ) -> bool
10041008 {
10051009 if (reverse)
10061010 speed = -speed;
10071011
10081012 if (item.reversed == reverse)
1009- return updateVehiclePosition (item.vehicle ->state .front , speed, isFirst, trainState_ ) &&
1010- updateVehiclePosition (item.vehicle ->state .rear , speed, false , trainState_ );
1013+ return updateVehiclePosition (item.vehicle ->state .front , speed, isFirst, train_ ) &&
1014+ updateVehiclePosition (item.vehicle ->state .rear , speed, false , train_ );
10111015 else
1012- return updateVehiclePosition (item.vehicle ->state .rear , speed, isFirst, trainState_ ) &&
1013- updateVehiclePosition (item.vehicle ->state .front , speed, false , trainState_ );
1016+ return updateVehiclePosition (item.vehicle ->state .rear , speed, isFirst, train_ ) &&
1017+ updateVehiclePosition (item.vehicle ->state .front , speed, false , train_ );
10141018 };
10151019
10161020 const float speed = m_stateData.powerOn ? trainState.speed : 0 .0f ;
@@ -1020,7 +1024,7 @@ void Simulator::updateTrainPositions()
10201024 {
10211025 for (auto & vehicleItem : train->vehicles )
10221026 {
1023- if (!updateHelper (vehicleItem, speed, trainState.reverse , isFirst, trainState ))
1027+ if (!updateHelper (vehicleItem, speed, trainState.reverse , isFirst, *train ))
10241028 {
10251029 trainState.speed = 0 .0f ;
10261030 trainState.speedOrDirectionChanged = true ;
@@ -1035,7 +1039,7 @@ void Simulator::updateTrainPositions()
10351039 {
10361040 for (auto & vehicleItem : train->vehicles | std::views::reverse)
10371041 {
1038- if (!updateHelper (vehicleItem, speed, trainState.reverse , isFirst, trainState ))
1042+ if (!updateHelper (vehicleItem, speed, trainState.reverse , isFirst, *train ))
10391043 {
10401044 trainState.speed = 0 .0f ;
10411045 trainState.speedOrDirectionChanged = true ;
@@ -1074,13 +1078,13 @@ inline bool isTurnoutUnknownState(const Simulator::TrackSegment& segment,
10741078
10751079bool Simulator::updateVehiclePosition (VehicleState::Face& face,
10761080 const float speed, bool isFirst_,
1077- TrainState &trainState_ )
1081+ Train &train )
10781082{
10791083 using Object = Simulator::TrackSegment::Object;
10801084
10811085 auto objHelper = [this ](const TrackSegment::Object& obj,
10821086 const float facePos, const float targetPos,
1083- TrainState &trainState , bool dirFwd_, bool isFirst, bool &stop) -> bool
1087+ Train &train_ , bool dirFwd_, bool isFirst, bool &stop) -> bool
10841088 {
10851089 if (dirFwd_)
10861090 {
@@ -1110,7 +1114,7 @@ bool Simulator::updateVehiclePosition(VehicleState::Face& face,
11101114 sensor.curTime = sensor.maxTime ;
11111115 sensor.occupied = 1 ;
11121116 }
1113- else if (isFirst && obj.type == Object::Type::MainSignal && trainState .mode != TrainState::Mode::Manual)
1117+ else if (isFirst && obj.type == Object::Type::MainSignal && train_. state .mode != TrainState::Mode::Manual)
11141118 {
11151119 auto it = m_stateData.mainSignals .find (obj.signalName );
11161120 if (it == m_stateData.mainSignals .end ())
@@ -1126,14 +1130,13 @@ bool Simulator::updateVehiclePosition(VehicleState::Face& face,
11261130 return false ;
11271131 }
11281132
1129- if (trainState. mode == TrainState::Mode::SemiAutomatic && trainState .speed == 0 )
1133+ if (train_. state . mode == TrainState::Mode::SemiAutomatic && train_. state .speed == 0 )
11301134 return true ;
11311135
11321136 // Apply signal speed on next tick
11331137 // TODO: train max speed
1134- trainState.speed = tickSpeed;
1135- trainState.speedOrDirectionChanged = true ;
1136- trainState.nextSignalDirty = true ;
1138+ setTrainSpeed (&train_, tickSpeed);
1139+ train_.state .nextSignalDirty = true ;
11371140 }
11381141
11391142 return true ;
@@ -1155,7 +1158,7 @@ bool Simulator::updateVehiclePosition(VehicleState::Face& face,
11551158 {
11561159 bool stop = false ;
11571160 if (objHelper (obj, face.distance , distance,
1158- trainState_ , true , isFirst_, stop))
1161+ train , true , isFirst_, stop))
11591162 continue ;
11601163
11611164 if (stop)
@@ -1169,7 +1172,7 @@ bool Simulator::updateVehiclePosition(VehicleState::Face& face,
11691172 {
11701173 bool stop = false ;
11711174 if (objHelper (obj, face.distance , distance,
1172- trainState_ , false , isFirst_, stop))
1175+ train , false , isFirst_, stop))
11731176 continue ;
11741177
11751178 if (stop)
@@ -1187,8 +1190,8 @@ bool Simulator::updateVehiclePosition(VehicleState::Face& face,
11871190 }
11881191
11891192 // If no signal was found rescan on segment change
1190- if (!trainState_ .nextSignal )
1191- trainState_ .nextSignalDirty = true ;
1193+ if (!train. state .nextSignal )
1194+ train. state .nextSignalDirty = true ;
11921195
11931196 auto & nextSegment = staticData.trackSegments [nextSegmentIndex];
11941197
@@ -1231,8 +1234,8 @@ bool Simulator::updateVehiclePosition(VehicleState::Face& face,
12311234 }
12321235
12331236 // If no signal was found rescan on segment change
1234- if (!trainState_ .nextSignal )
1235- trainState_ .nextSignalDirty = true ;
1237+ if (!train. state .nextSignal )
1238+ train. state .nextSignalDirty = true ;
12361239
12371240 auto & nextSegment = staticData.trackSegments [nextSegmentIndex];
12381241
@@ -2560,6 +2563,9 @@ void Simulator::updateTrainNextSignal(Train *train)
25602563 segmentIndex = nextSegmentIndex;
25612564 }
25622565
2566+ if (train->state .reverse )
2567+ inverted = !inverted;
2568+
25632569 dirFwd = inverted == train->state .reverse ;
25642570
25652571 startPos = 0.0 ;
@@ -2598,8 +2604,7 @@ bool Simulator::checkNextSignal(Train *train)
25982604 if (train->state .mode == TrainState::Mode::Automatic && train->state .speed == 0 .0f )
25992605 {
26002606 // Start at 30 km/h until next signal is found
2601- train->state .speed = 30 * SpeedKmHtoTick;
2602- train->state .speedOrDirectionChanged = true ;
2607+ setTrainSpeed (train, 30 * SpeedKmHtoTick);
26032608 }
26042609 }
26052610
@@ -2617,7 +2622,7 @@ bool Simulator::checkNextSignal(Train *train)
26172622 if (!train->state .nextSignal )
26182623 {
26192624 const float length = getSegmentLength (staticData.trackSegments [segmentIndex], m_stateData);
2620- if (length >= 400 )
2625+ if (length >= 100 )
26212626 {
26222627 // Long segments do not find signal and also do not set dirty
26232628 // Set dirty near to end to re-trigger signal scan
@@ -2714,20 +2719,18 @@ bool Simulator::checkNextSignal(Train *train)
27142719 targetSpeed = std::min (targetSpeed, train->speedMax );
27152720 if (targetSpeed < train->state .speed )
27162721 {
2717- train->state .speed = targetSpeed;
2718- train->state .speedOrDirectionChanged = true ;
2722+ setTrainSpeed (train, targetSpeed);
27192723
27202724 if (train->state .speed == 0 )
27212725 return false ; // Stop
27222726 }
27232727 }
2724- else if (train->state .mode == TrainState::Mode::Automatic && train->state .speed == 0 . 0f )
2728+ else if (train->state .mode == TrainState::Mode::Automatic && train->state .speed < train-> state . nextSignal -> maxSpeed * SpeedKmHtoTick )
27252729 {
2726- if (train->state .nextSignal -> maxSpeed > 0 || totalDistance > 10 )
2730+ if (train->state .speed < 30 * SpeedKmHtoTick )
27272731 {
27282732 // Get near at 30 km/h to next signal
2729- train->state .speed = 30 * SpeedKmHtoTick;
2730- train->state .speedOrDirectionChanged = true ;
2733+ setTrainSpeed (train, 30 * SpeedKmHtoTick);
27312734 }
27322735 }
27332736
0 commit comments