16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 10:29:19 +02:00

interior lighting power source lookup enhancement, track event activation filtering, switch geometry normal fix, material parsing enhancements, AI acceleration and braking logic tweaks, AI car route scanning accuracy fix, AI braking delay fix

This commit is contained in:
tmj-fstate
2018-08-17 01:17:22 +02:00
parent 5e52467746
commit 4aeb98ecbe
8 changed files with 247 additions and 332 deletions

View File

@@ -479,9 +479,17 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
// jeśli w kierunku Point2 toru // jeśli w kierunku Point2 toru
fTrackLength = pTrack->Length() - fTrackLength; // przeskanowana zostanie odległość do Point2 fTrackLength = pTrack->Length() - fTrackLength; // przeskanowana zostanie odległość do Point2
} }
fTrackLength -= pVehicle->tracing_offset(); // account for the fact tracing begins from active axle, not the actual front of the vehicle
fCurrentDistance = -fLength - fTrackLength; // aktualna odległość ma być ujemna gdyż jesteśmy na końcu składu // NOTE: position of the couplers is modified by track offset, but the axles ain't, so we need to account for this as well
fLastVel = -1.0; // pTrack->VelocityGet(); // aktualna prędkość // changed to -1 to recognize speed limit, if any fTrackLength -= (
pVehicle->AxlePositionGet()
- pVehicle->RearPosition()
+ pVehicle->VectorLeft() * pVehicle->MoverParameters->OffsetTrackH )
.Length();
// aktualna odległość ma być ujemna gdyż jesteśmy na końcu składu
fCurrentDistance = -fLength - fTrackLength;
// aktualna prędkość // changed to -1 to recognize speed limit, if any
fLastVel = -1.0;
sSpeedTable.clear(); sSpeedTable.clear();
iLast = -1; iLast = -1;
tLast = nullptr; //żaden nie sprawdzony tLast = nullptr; //żaden nie sprawdzony
@@ -1429,13 +1437,13 @@ TController::braking_distance_multiplier( float const Targetvelocity ) const {
return interpolate( 2.f, 1.f, static_cast<float>( mvOccupied->Vel / 40.0 ) ); return interpolate( 2.f, 1.f, static_cast<float>( mvOccupied->Vel / 40.0 ) );
} }
// HACK: cargo trains or trains going downhill with high braking threshold need more distance to come to a full stop // HACK: cargo trains or trains going downhill with high braking threshold need more distance to come to a full stop
if( ( fBrake_a0[ 0 ] > 0.2 ) if( ( fBrake_a0[ 1 ] > 0.2 )
&& ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ) && ( ( true == IsCargoTrain )
|| ( fAccGravity > 0.025 ) ) { || ( fAccGravity > 0.025 ) ) ) {
return interpolate( return interpolate(
1.f, 2.f, 1.f, 2.f,
clamp( clamp(
( fBrake_a0[ 0 ] - 0.2 ) / 0.2, ( fBrake_a0[ 1 ] - 0.2 ) / 0.2,
0.0, 1.0 ) ); 0.0, 1.0 ) );
} }
@@ -1868,59 +1876,71 @@ void TController::AutoRewident()
} }
d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła) d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła)
} }
//teraz zerujemy tabelkę opóźnienia hamowania //ustawianie trybu pracy zadajnika hamulca, wystarczy raz po inicjalizacji AI
double velstep = (mvOccupied->Vmax*0.5) / BrakeAccTableSize; for( int i = 1; i <= 8; i *= 2 ) {
for (int i = 0; i < BrakeAccTableSize; i++) if( ( mvOccupied->BrakeOpModes & i ) > 0 ) {
mvOccupied->BrakeOpModeFlag = i;
}
}
// teraz zerujemy tabelkę opóźnienia hamowania
for (int i = 0; i < BrakeAccTableSize; ++i)
{ {
fBrake_a0[i+1] = 0; fBrake_a0[i+1] = 0;
fBrake_a1[i+1] = 0; fBrake_a1[i+1] = 0;
} }
// 4. Przeliczanie siły hamowania // 4. Przeliczanie siły hamowania
double const velstep = ( mvOccupied->Vmax*0.5 ) / BrakeAccTableSize;
d = pVehicles[0]; // pojazd na czele składu d = pVehicles[0]; // pojazd na czele składu
// HACK: calculated brake thresholds for cars are so high they prevent the AI from effectively braking
// thus we artificially reduce them until a better solution for the problem is found
auto const braketablescale { (
d->MoverParameters->CategoryFlag == 2 ?
0.6 :
1.0 ) };
while (d) { while (d) {
for( int i = 0; i < BrakeAccTableSize; ++i ) { for( int i = 0; i < BrakeAccTableSize; ++i ) {
fBrake_a0[ i + 1 ] += braketablescale * d->MoverParameters->BrakeForceR( 0.25, velstep*( 1 + 2 * i ) ); fBrake_a0[ i + 1 ] += d->MoverParameters->BrakeForceR( 0.25, velstep*( 1 + 2 * i ) );
fBrake_a1[ i + 1 ] += braketablescale * d->MoverParameters->BrakeForceR( 1.00, velstep*( 1 + 2 * i ) ); fBrake_a1[ i + 1 ] += d->MoverParameters->BrakeForceR( 1.00, velstep*( 1 + 2 * i ) );
} }
d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła) d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła)
} }
for (int i = 0; i < BrakeAccTableSize; i++) for (int i = 0; i < BrakeAccTableSize; ++i)
{ {
fBrake_a1[i+1] -= fBrake_a0[i+1]; fBrake_a1[i+1] -= fBrake_a0[i+1];
fBrake_a0[i+1] /= fMass; fBrake_a0[i+1] /= fMass;
fBrake_a0[i + 1] += 0.001*velstep*(1 + 2 * i); fBrake_a0[i + 1] += 0.001*velstep*(1 + 2 * i);
fBrake_a1[i+1] /= (12*fMass); fBrake_a1[i+1] /= (12*fMass);
} }
IsCargoTrain = ( mvOccupied->CategoryFlag == 1 ) && ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 );
IsHeavyCargoTrain = ( true == IsCargoTrain ) && ( fBrake_a0[ 1 ] > 0.4 );
BrakingInitialLevel = (
IsHeavyCargoTrain ? 1.25 :
IsCargoTrain ? 1.25 :
1.00 );
BrakingLevelIncrease = (
IsHeavyCargoTrain ? 0.25 :
IsCargoTrain ? 0.25 :
0.25 );
if( mvOccupied->TrainType == dt_EZT ) { if( mvOccupied->TrainType == dt_EZT ) {
fAccThreshold = std::max(-fBrake_a0[BrakeAccTableSize] - 8 * fBrake_a1[BrakeAccTableSize], -0.55); fAccThreshold = std::max( -0.55, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
fBrakeReaction = 0.25; fBrakeReaction = 0.25;
} }
else if( mvOccupied->TrainType == dt_DMU ) { else if( mvOccupied->TrainType == dt_DMU ) {
fAccThreshold = std::max( -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ], -0.45 ); fAccThreshold = std::max( -0.45, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
fBrakeReaction = 0.25; fBrakeReaction = 0.25;
} }
else if (ustaw > 16) else if (ustaw > 16) {
{ fAccThreshold = -fBrake_a0[ BrakeAccTableSize ] - 4 * fBrake_a1[ BrakeAccTableSize ];
fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 4 * fBrake_a1[BrakeAccTableSize];
fBrakeReaction = 1.00 + fLength*0.004; fBrakeReaction = 1.00 + fLength*0.004;
} }
else else {
{ fAccThreshold = -fBrake_a0[ BrakeAccTableSize ] - 1 * fBrake_a1[ BrakeAccTableSize ];
fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 1 * fBrake_a1[BrakeAccTableSize];
fBrakeReaction = 1.00 + fLength*0.005; fBrakeReaction = 1.00 + fLength*0.005;
} }
for (int i = 1; i <= 8; i *= 2) //ustawianie trybu pracy zadajnika hamulca, wystarczy raz po inicjalizacji AI /*
{ if( IsHeavyCargoTrain ) {
if ((mvOccupied->BrakeOpModes & i) > 0) { // HACK: heavy cargo trains don't activate brakes early enough
mvOccupied->BrakeOpModeFlag = i; fAccThreshold = std::max( -0.2, fAccThreshold );
} }
} */
} }
double TController::ESMVelocity(bool Main) double TController::ESMVelocity(bool Main)
@@ -2418,7 +2438,10 @@ bool TController::PrepareEngine()
mvControlling->IncMainCtrl( 1 ); mvControlling->IncMainCtrl( 1 );
} }
} }
mvControlling->MainSwitch(true); if( ( mvControlling->EnginePowerSource.SourceType != TPowerSource::CurrentCollector )
|| ( std::max( mvControlling->GetTrainsetVoltage(), std::abs( mvControlling->RunningTraction.TractionVoltage ) ) > mvControlling->EnginePowerSource.CollectorParameters.MinV ) ) {
mvControlling->MainSwitch( true );
}
/* /*
if (mvControlling->EngineType == DieselEngine) { if (mvControlling->EngineType == DieselEngine) {
// Ra 2014-06: dla SN61 trzeba wrzucić pierwszą pozycję - nie wiem, czy tutaj... // Ra 2014-06: dla SN61 trzeba wrzucić pierwszą pozycję - nie wiem, czy tutaj...
@@ -2621,7 +2644,9 @@ bool TController::IncBrake()
d = pVehicles[0]; // pojazd na czele składu d = pVehicles[0]; // pojazd na czele składu
while (d) while (d)
{ // przeliczanie dodatkowego potrzebnego spadku ciśnienia { // przeliczanie dodatkowego potrzebnego spadku ciśnienia
pos_corr+=(d->MoverParameters->Hamulec->GetCRP() - 5.0)*d->MoverParameters->TotalMass; if( ( d->MoverParameters->Hamulec->GetBrakeStatus() & b_dmg ) == 0 ) {
pos_corr += ( d->MoverParameters->Hamulec->GetCRP() - 5.0 ) * d->MoverParameters->TotalMass;
}
d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła) d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła)
} }
pos_corr = pos_corr / fMass * 2.5; pos_corr = pos_corr / fMass * 2.5;
@@ -2636,10 +2661,7 @@ bool TController::IncBrake()
if( deltaAcc > fBrake_a1[0]) if( deltaAcc > fBrake_a1[0])
{ {
if( mvOccupied->BrakeCtrlPosR < 0.1 ) { if( mvOccupied->BrakeCtrlPosR < 0.1 ) {
OK = mvOccupied->BrakeLevelAdd( ( OK = mvOccupied->BrakeLevelAdd( BrakingInitialLevel );
mvOccupied->BrakeDelayFlag > bdelay_G ?
1.0 :
1.25 ) );
/* /*
// HACK: stronger braking to overcome SA134 engine behaviour // HACK: stronger braking to overcome SA134 engine behaviour
if( ( mvOccupied->TrainType == dt_DMU ) if( ( mvOccupied->TrainType == dt_DMU )
@@ -2654,10 +2676,11 @@ bool TController::IncBrake()
} }
else else
{ {
OK = mvOccupied->BrakeLevelAdd( 0.25 ); OK = mvOccupied->BrakeLevelAdd( BrakingLevelIncrease );
if( ( deltaAcc > 5 * fBrake_a1[ 0 ] ) // brake harder if the acceleration is much higher than desired
&& ( mvOccupied->BrakeCtrlPosR <= 3.0 ) ) { if( ( deltaAcc > 2 * fBrake_a1[ 0 ] )
mvOccupied->BrakeLevelAdd( 0.75 ); && ( mvOccupied->BrakeCtrlPosR + BrakingLevelIncrease <= 5.0 ) ) {
mvOccupied->BrakeLevelAdd( BrakingLevelIncrease );
} }
} }
} }
@@ -2793,36 +2816,42 @@ bool TController::IncSpeed()
// na pozycji 0 przejdzie, a na pozostałych będzie czekać, aż się załączą liniowe (zgaśnie DelayCtrlFlag) // na pozycji 0 przejdzie, a na pozostałych będzie czekać, aż się załączą liniowe (zgaśnie DelayCtrlFlag)
if (Ready || (iDrivigFlags & movePress)) { if (Ready || (iDrivigFlags & movePress)) {
// use series mode: // use series mode:
// to build up speed to 30/40 km/h for passenger/cargo train (10 km/h less if going uphill)
// if high threshold is set for motor overload relay, // if high threshold is set for motor overload relay,
// if the power station is heavily burdened // if the power station is heavily burdened,
// if it generates enough traction force
// to build up speed to 30/40 km/h for passenger/cargo train (10 km/h less if going uphill)
auto const sufficienttractionforce { std::abs( mvControlling->Ft ) > ( IsHeavyCargoTrain ? 125 : 100 ) * 1000.0 };
auto const useseriesmodevoltage { 0.80 * mvControlling->EnginePowerSource.CollectorParameters.MaxV }; auto const useseriesmodevoltage { 0.80 * mvControlling->EnginePowerSource.CollectorParameters.MaxV };
auto const seriesmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 ) };
auto const parallelmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 ) };
auto const useseriesmode = ( auto const useseriesmode = (
( mvOccupied->Vel <= ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ? 35 : 25 ) + ( mvControlling->ScndCtrlPos == 0 ? 0 : 5 ) - ( ( fAccGravity < -0.025 ) ? 10 : 0 ) ) ( mvControlling->Imax > mvControlling->ImaxLo )
|| ( mvControlling->Imax > mvControlling->ImaxLo ) || ( fVoltage < useseriesmodevoltage )
|| ( fVoltage < useseriesmodevoltage ) ); || ( ( true == sufficienttractionforce )
&& ( mvOccupied->Vel <= ( IsCargoTrain ? 35 : 25 ) + ( seriesmodefieldshunting ? 5 : 0 ) - ( ( fAccGravity < -0.025 ) ? 10 : 0 ) ) ) );
// when not in series mode use the first available parallel mode configuration until 50/60 km/h for passenger/cargo train // when not in series mode use the first available parallel mode configuration until 50/60 km/h for passenger/cargo train
// (if there's only one parallel mode configuration it'll be used regardless of current speed) // (if there's only one parallel mode configuration it'll be used regardless of current speed)
auto const scndctrl = ( auto const usefieldshunting = (
( mvControlling->StLinFlag ) ( mvControlling->StLinFlag )
&& ( mvControlling->RList[ mvControlling->MainCtrlPos ].R < 0.01 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].R < 0.01 )
&& ( useseriesmode ? && ( useseriesmode ?
mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 : mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 :
( ( mvOccupied->Vel <= ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ? 55 : 45 ) + ( mvControlling->ScndCtrlPos == 0 ? 0 : 5 ) ) ? ( ( true == sufficienttractionforce )
&& ( mvOccupied->Vel <= ( IsCargoTrain ? 55 : 45 ) + ( parallelmodefieldshunting ? 5 : 0 ) ) ?
mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 : mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 :
mvControlling->MainCtrlPos == mvControlling->MainCtrlPosNo ) ) ); mvControlling->MainCtrlPos == mvControlling->MainCtrlPosNo ) ) );
double Vs = 99999; double Vs = 99999;
if( scndctrl ? if( usefieldshunting ?
( mvControlling->ScndCtrlPos < mvControlling->ScndCtrlPosNo ) : ( mvControlling->ScndCtrlPos < mvControlling->ScndCtrlPosNo ) :
( mvControlling->MainCtrlPos < mvControlling->MainCtrlPosNo ) ) { ( mvControlling->MainCtrlPos < mvControlling->MainCtrlPosNo ) ) {
Vs = ESMVelocity( !scndctrl ); Vs = ESMVelocity( !usefieldshunting );
} }
if( ( std::abs( mvControlling->Im ) < ( fReady < 0.4 ? mvControlling->Imin : mvControlling->IminLo ) ) if( ( std::abs( mvControlling->Im ) < ( fReady < 0.4 ? mvControlling->Imin : mvControlling->IminLo ) )
|| ( mvControlling->Vel > Vs ) ) { || ( mvControlling->Vel > Vs ) ) {
// Ra: wywalał nadmiarowy, bo Im może być ujemne; jak nie odhamowany, to nie przesadzać z prądem // Ra: wywalał nadmiarowy, bo Im może być ujemne; jak nie odhamowany, to nie przesadzać z prądem
if( scndctrl ) { if( usefieldshunting ) {
// to dać bocznik // to dać bocznik
// engage the shuntfield only if there's sufficient power margin to draw from // engage the shuntfield only if there's sufficient power margin to draw from
OK = ( OK = (
@@ -3787,12 +3816,13 @@ TController::UpdateSituation(double dt) {
// Ra: odluźnianie przeładowanych lokomotyw, ciągniętych na zimno - prowizorka... // Ra: odluźnianie przeładowanych lokomotyw, ciągniętych na zimno - prowizorka...
if (AIControllFlag) // skład jak dotąd był wyluzowany if (AIControllFlag) // skład jak dotąd był wyluzowany
{ {
if (mvOccupied->BrakeCtrlPos == 0) // jest pozycja jazdy if( ( mvOccupied->BrakeCtrlPos == 0 ) // jest pozycja jazdy
if ((p->MoverParameters->PipePress - 5.0) > && ( ( p->MoverParameters->Hamulec->GetBrakeStatus() & b_dmg ) == 0 ) // brake isn't broken
-0.1) // jeśli ciśnienie jak dla jazdy && ( p->MoverParameters->PipePress - 5.0 > -0.1 ) // jeśli ciśnienie jak dla jazdy
if (p->MoverParameters->Hamulec->GetCRP() > && ( p->MoverParameters->Hamulec->GetCRP() > p->MoverParameters->PipePress + 0.12 ) ) { // za dużo w zbiorniku
p->MoverParameters->PipePress + 0.12) // za dużo w zbiorniku // indywidualne luzowanko
p->MoverParameters->BrakeReleaser(1); // indywidualne luzowanko p->MoverParameters->BrakeReleaser( 1 );
}
if (p->MoverParameters->Power > 0.01) // jeśli ma silnik if (p->MoverParameters->Power > 0.01) // jeśli ma silnik
if (p->MoverParameters->FuseFlag) // wywalony nadmiarowy if (p->MoverParameters->FuseFlag) // wywalony nadmiarowy
Need_TryAgain = true; // reset jak przy wywaleniu nadmiarowego Need_TryAgain = true; // reset jak przy wywaleniu nadmiarowego
@@ -4355,34 +4385,14 @@ TController::UpdateSituation(double dt) {
} }
case Shunt: { case Shunt: {
// na jaką odleglość i z jaką predkością ma podjechać // na jaką odleglość i z jaką predkością ma podjechać
/* // TODO: test if we can use the distances calculation from obey_train
fMinProximityDist = 5.0;
fMaxProximityDist = 10.0; //[m]
if( pVehicles[ 0 ] != pVehicles[ 1 ] ) {
// for larger consists increase margins to account for slower braking etc
// NOTE: this will affect also multi-unit vehicles TBD: is this what we want?
fMinProximityDist *= 2.0;
fMaxProximityDist *= 2.0;
if( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ) {
// additional safety margin for cargo consists
fMinProximityDist *= 2.0;
fMaxProximityDist *= 2.0;
if( fBrake_a0[ 0 ] >= 0.35 ) {
// cargo trains with high braking threshold may require even larger safety margin
fMaxProximityDist += 20.0;
}
}
}
*/
fMinProximityDist = std::min( 5 + iVehicles, 25 ); fMinProximityDist = std::min( 5 + iVehicles, 25 );
fMaxProximityDist = std::min( 10 + iVehicles, 50 ); fMaxProximityDist = std::min( 10 + iVehicles, 50 );
if( ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ) /*
&& ( fBrake_a0[ 0 ] >= 0.35 ) ) { if( IsHeavyCargoTrain ) {
// cargo trains with high braking threshold may require even larger safety margin
fMaxProximityDist *= 1.5; fMaxProximityDist *= 1.5;
} }
*/
fVelPlus = 2.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania fVelPlus = 2.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania
// margines prędkości powodujący załączenie napędu // margines prędkości powodujący załączenie napędu
// były problemy z jazdą np. 3km/h podczas ładowania wagonów // były problemy z jazdą np. 3km/h podczas ładowania wagonów
@@ -4393,11 +4403,25 @@ TController::UpdateSituation(double dt) {
// na jaka odleglosc i z jaka predkoscia ma podjechac do przeszkody // na jaka odleglosc i z jaka predkoscia ma podjechac do przeszkody
if( mvOccupied->CategoryFlag & 1 ) { if( mvOccupied->CategoryFlag & 1 ) {
// jeśli pociąg // jeśli pociąg
fMinProximityDist = 15.0; fMinProximityDist = clamp( 5 + iVehicles, 10, 15 );
fMaxProximityDist = fMaxProximityDist = clamp( 10 + iVehicles, 15, 40 );
( mvOccupied->Vel > 0.0 ) ?
25.0 : if( IsCargoTrain ) {
50.0; //[m] jak stanie za daleko, to niech nie dociąga paru metrów // increase distances for cargo trains to take into account slower reaction to brakes
fMinProximityDist += 10.0;
fMaxProximityDist += 10.0;
/*
if( IsHeavyCargoTrain ) {
// cargo trains with high braking threshold may require even larger safety margin
fMaxProximityDist += 20.0;
}
*/
}
if( mvOccupied->Vel < 0.1 ) {
// jak stanie za daleko, to niech nie dociąga paru metrów
fMaxProximityDist = 50.0;
}
if( iDrivigFlags & moveLate ) { if( iDrivigFlags & moveLate ) {
// jeśli spóźniony, to gna // jeśli spóźniony, to gna
fVelMinus = 1.0; fVelMinus = 1.0;
@@ -4412,20 +4436,11 @@ TController::UpdateSituation(double dt) {
// bottom margin raised to 2 km/h to give the AI more leeway at low speed limits // bottom margin raised to 2 km/h to give the AI more leeway at low speed limits
fVelPlus = clamp( std::ceil( 0.05 * VelDesired ), 2.0, 5.0 ); fVelPlus = clamp( std::ceil( 0.05 * VelDesired ), 2.0, 5.0 );
} }
if( mvOccupied->BrakeDelayFlag == bdelay_G ) {
// increase distances for cargo trains to take into account slower reaction to brakes
fMinProximityDist += 10.0;
fMaxProximityDist += 15.0;
if( fBrake_a0[ 0 ] >= 0.35 ) {
// cargo trains with high braking threshold may require even larger safety margin
fMaxProximityDist += 20.0;
}
}
} }
else { else {
// samochod (sokista też) // samochod (sokista też)
fMinProximityDist = std::max( 3.0, mvOccupied->Vel * 0.2 ); fMinProximityDist = std::max( 3.5, mvOccupied->Vel * 0.2 );
fMaxProximityDist = std::max( 9.0, mvOccupied->Vel * 0.375 ); //[m] fMaxProximityDist = std::max( 9.5, mvOccupied->Vel * 0.375 ); //[m]
// margines prędkości powodujący załączenie napędu // margines prędkości powodujący załączenie napędu
fVelMinus = 2.0; fVelMinus = 2.0;
// dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania
@@ -4701,14 +4716,15 @@ TController::UpdateSituation(double dt) {
fMinProximityDist : // cars can bunch up tighter fMinProximityDist : // cars can bunch up tighter
fMaxProximityDist ) ); // other vehicle types less so fMaxProximityDist ) ); // other vehicle types less so
*/ */
ActualProximityDist = std::min(
ActualProximityDist,
vehicle->fTrackBlock );
double k = coupler->Connected->Vel; // prędkość pojazdu z przodu (zakładając, double k = coupler->Connected->Vel; // prędkość pojazdu z przodu (zakładając,
// że jedzie w tę samą stronę!!!) // że jedzie w tę samą stronę!!!)
if( k - vel < 10 ) { if( k - vel < 5 ) {
// porównanie modułów prędkości [km/h] // porównanie modułów prędkości [km/h]
// zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej // zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej
ActualProximityDist = std::min(
ActualProximityDist,
vehicle->fTrackBlock );
double const distance = vehicle->fTrackBlock - fMaxProximityDist - ( fBrakeDist * 1.15 ); // odległość bezpieczna zależy od prędkości double const distance = vehicle->fTrackBlock - fMaxProximityDist - ( fBrakeDist * 1.15 ); // odległość bezpieczna zależy od prędkości
if( distance < 0.0 ) { if( distance < 0.0 ) {
// jeśli odległość jest zbyt mała // jeśli odległość jest zbyt mała
@@ -4939,13 +4955,17 @@ TController::UpdateSituation(double dt) {
} }
else { else {
// outside of max safe range // outside of max safe range
AccDesired = AccPreferred;
if( vel > min_speed( 10.0, VelDesired ) ) { if( vel > min_speed( 10.0, VelDesired ) ) {
// allow to coast at reasonably low speed // allow to coast at reasonably low speed
auto const brakingdistance { fBrakeDist * braking_distance_multiplier( VelNext ) };
auto const slowdowndistance { ( auto const slowdowndistance { (
( OrderCurrentGet() & Connect ) == 0 ? mvOccupied->CategoryFlag == 2 ? // cars can stop on a dime, for bigger vehicles we enforce some minimal braking distance
100.0 : brakingdistance :
25.0 ) }; std::max(
if( ( std::max( slowdowndistance, fMaxProximityDist ) + fBrakeDist * braking_distance_multiplier( VelNext ) ) >= ( ActualProximityDist - fMaxProximityDist ) ) { ( ( OrderCurrentGet() & Connect ) == 0 ? 100.0 : 25.0 ),
brakingdistance ) ) };
if( ( brakingdistance + std::max( slowdowndistance, fMaxProximityDist ) ) >= ( ActualProximityDist - fMaxProximityDist ) ) {
// don't slow down prematurely; as long as we have room to come to a full stop at a safe distance, we're good // don't slow down prematurely; as long as we have room to come to a full stop at a safe distance, we're good
// ensure some minimal coasting speed, otherwise a vehicle entering this zone at very low speed will be crawling forever // ensure some minimal coasting speed, otherwise a vehicle entering this zone at very low speed will be crawling forever
auto const brakingpointoffset = VelNext * braking_distance_multiplier( VelNext ); auto const brakingpointoffset = VelNext * braking_distance_multiplier( VelNext );
@@ -5060,8 +5080,8 @@ TController::UpdateSituation(double dt) {
// if it looks like we'll exceed maximum speed start thinking about slight slowing down // if it looks like we'll exceed maximum speed start thinking about slight slowing down
AccDesired = std::min( AccDesired, -0.25 ); AccDesired = std::min( AccDesired, -0.25 );
// HACK: for cargo trains with high braking threshold ensure we cross that threshold // HACK: for cargo trains with high braking threshold ensure we cross that threshold
if( ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ) if( ( true == IsCargoTrain )
&& ( fBrake_a0[ 0 ] > 0.2 ) ) { && ( fBrake_a0[ 0 ] > 0.2 ) ) {
AccDesired -= clamp( fBrake_a0[ 0 ] - 0.2, 0.0, 0.15 ); AccDesired -= clamp( fBrake_a0[ 0 ] - 0.2, 0.0, 0.15 );
} }
} }
@@ -5119,7 +5139,10 @@ TController::UpdateSituation(double dt) {
// last step sanity check, until the whole calculation is straightened out // last step sanity check, until the whole calculation is straightened out
AccDesired = std::min( AccDesired, AccPreferred ); AccDesired = std::min( AccDesired, AccPreferred );
AccDesired = clamp( AccDesired, -0.9, 0.9 ); AccDesired = clamp(
AccDesired,
( mvControlling->CategoryFlag == 2 ? -2.0 : -0.9 ),
( mvControlling->CategoryFlag == 2 ? 2.0 : 0.9 ) );
if (AIControllFlag) { if (AIControllFlag) {
// część wykonawcza tylko dla AI, dla człowieka jedynie napisy // część wykonawcza tylko dla AI, dla człowieka jedynie napisy
@@ -5211,7 +5234,7 @@ TController::UpdateSituation(double dt) {
&& ( BrakeChargingCooldown >= 0.0 ) ) { && ( BrakeChargingCooldown >= 0.0 ) ) {
if( ( iDrivigFlags & moveOerlikons ) if( ( iDrivigFlags & moveOerlikons )
|| ( mvOccupied->BrakeDelayFlag & bdelay_G ) ) { || ( true == IsCargoTrain ) ) {
// napełnianie w Oerlikonie // napełnianie w Oerlikonie
mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) ); mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) );
// don't charge the brakes too often, or we risk overcharging // don't charge the brakes too often, or we risk overcharging

View File

@@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/.
#include "Classes.h" #include "Classes.h"
#include "mczapkie/mover.h" #include "mczapkie/mover.h"
#include "sound.h" #include "sound.h"
#include "dynobj.h"
enum TOrders enum TOrders
{ // rozkazy dla AI { // rozkazy dla AI
@@ -208,8 +209,15 @@ public:
double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h) double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h)
double fAccThreshold = 0.0; // próg opóźnienia dla zadziałania hamulca double fAccThreshold = 0.0; // próg opóźnienia dla zadziałania hamulca
double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca
double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca // dla fBrake_aX:
double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca // indeks [0] - wartości odpowiednie dla aktualnej prędkości
// a potem jest 20 wartości dla różnych prędkości zmieniających się co 5 % Vmax pojazdu obsadzonego
double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // opóźnienia hamowania przy ustawieniu zaworu maszynisty w pozycji 1.0
double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // przyrost opóźnienia hamowania po przestawieniu zaworu maszynisty o 0,25 pozycji
double BrakingInitialLevel{ 1.0 };
double BrakingLevelIncrease{ 0.25 };
bool IsCargoTrain{ false };
bool IsHeavyCargoTrain{ false };
double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku
double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI
double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
@@ -354,7 +362,7 @@ private:
std::vector<TEvent *> CheckTrackEvent(TTrack *Track, double const fDirection ) const; std::vector<TEvent *> CheckTrackEvent(TTrack *Track, double const fDirection ) const;
bool TableAddNew(); bool TableAddNew();
bool TableNotFound(TEvent const *Event) const; bool TableNotFound(TEvent const *Event) const;
void TableTraceRoute(double fDistance, TDynamicObject *pVehicle = nullptr); void TableTraceRoute(double fDistance, TDynamicObject *pVehicle);
void TableCheck(double fDistance); void TableCheck(double fDistance);
TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc); TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc);
// modifies brake distance for low target speeds, to ease braking rate in such situations // modifies brake distance for low target speeds, to ease braking rate in such situations
@@ -412,4 +420,8 @@ private:
std::string OwnerName() const; std::string OwnerName() const;
TMoverParameters const *Controlling() const { TMoverParameters const *Controlling() const {
return mvControlling; } return mvControlling; }
int Direction() const {
return iDirection; }
TDynamicObject const *Vehicle() const {
return pVehicle; }
}; };

View File

@@ -2772,66 +2772,6 @@ bool TDynamicObject::Update(double dt, double dt1)
if (!bEnabled) if (!bEnabled)
return false; // a normalnie powinny mieć bEnabled==false return false; // a normalnie powinny mieć bEnabled==false
// McZapkie-260202
if ((MoverParameters->EnginePowerSource.SourceType == TPowerSource::CurrentCollector) &&
(MoverParameters->Power > 1.0)) // aby rozrządczy nie opuszczał silnikowemu
/*
if ((MechInside) || (MoverParameters->TrainType == dt_EZT))
{
*/
// if
// ((!MoverParameters->PantCompFlag)&&(MoverParameters->CompressedVolume>=2.8))
// MoverParameters->PantVolume=MoverParameters->CompressedVolume;
if( MoverParameters->PantPress < MoverParameters->EnginePowerSource.CollectorParameters.MinPress ) {
// 3.5 wg http://www.transportszynowy.pl/eu06-07pneumat.php
if( true == MoverParameters->PantPressSwitchActive ) {
// opuszczenie pantografów przy niskim ciśnieniu
/*
// NOTE: disabled, the pantographs drop by themseleves when the pantograph tank pressure gets low enough
MoverParameters->PantFront( false, ( MoverParameters->TrainType == dt_EZT ? range::unit : range::local ) );
MoverParameters->PantRear( false, ( MoverParameters->TrainType == dt_EZT ? range::unit : range::local ) );
*/
if( MoverParameters->TrainType != dt_EZT ) {
// pressure switch safety measure -- open the line breaker, unless there's alternate source of traction voltage
if( MoverParameters->GetTrainsetVoltage() < 0.5 * MoverParameters->EnginePowerSource.MaxVoltage ) {
// TODO: check whether line breaker should be open EMU-wide
MoverParameters->MainSwitch( false, ( MoverParameters->TrainType == dt_EZT ? range_t::unit : range_t::local ) );
}
}
else {
// specialized variant for EMU -- pwr system disables converter and heating,
// and prevents their activation until pressure switch is set again
MoverParameters->PantPressLockActive = true;
// TODO: separate 'heating allowed' from actual heating flag, so we can disable it here without messing up heating toggle
MoverParameters->ConverterSwitch( false, range_t::unit );
}
// mark the pressure switch as spent
MoverParameters->PantPressSwitchActive = false;
}
}
else {
if( MoverParameters->PantPress >= 4.6 ) {
// NOTE: we require active low power source to prime the pressure switch
// this is a work-around for potential isssues caused by the switch activating on otherwise idle vehicles, but should check whether it's accurate
if( ( true == MoverParameters->Battery )
|| ( true == MoverParameters->ConverterFlag ) ) {
// prime the pressure switch
MoverParameters->PantPressSwitchActive = true;
// turn off the subsystems lock
MoverParameters->PantPressLockActive = false;
}
if( MoverParameters->PantPress >= 4.8 ) {
// Winger - automatyczne wylaczanie malej sprezarki
// TODO: governor lock, disables usage until pressure drop below 3.8 (should really make compressor object we could reuse)
MoverParameters->PantCompFlag = false;
}
}
}
/*
} // Ra: do Mover to trzeba przenieść, żeby AI też mogło sobie podpompować
*/
double dDOMoveLen; double dDOMoveLen;
TLocation l; TLocation l;

View File

@@ -733,8 +733,9 @@ void TMoverParameters::UpdatePantVolume(double dt)
// Ra 2014-07: kurek trójdrogowy łączy spr.pom. z pantografami i wyłącznikiem ciśnieniowym WS // Ra 2014-07: kurek trójdrogowy łączy spr.pom. z pantografami i wyłącznikiem ciśnieniowym WS
// Ra 2014-07: zbiornika rozrządu nie pompuje się tu, tylko pantografy; potem można zamknąć // Ra 2014-07: zbiornika rozrządu nie pompuje się tu, tylko pantografy; potem można zamknąć
// WS i odpalić resztę // WS i odpalić resztę
if ((TrainType == dt_EZT) ? (PantPress < ScndPipePress) : if ((TrainType == dt_EZT) ?
bPantKurek3) // kurek zamyka połączenie z ZG (PantPress < ScndPipePress) :
bPantKurek3) // kurek zamyka połączenie z ZG
{ // zbiornik pantografu połączony ze zbiornikiem głównym - małą sprężarką się tego nie napompuje { // zbiornik pantografu połączony ze zbiornikiem głównym - małą sprężarką się tego nie napompuje
// Ra 2013-12: Niebugocław mówi, że w EZT nie ma potrzeby odcinać kurkiem // Ra 2013-12: Niebugocław mówi, że w EZT nie ma potrzeby odcinać kurkiem
PantPress = ScndPipePress; PantPress = ScndPipePress;
@@ -758,33 +759,48 @@ void TMoverParameters::UpdatePantVolume(double dt)
} }
if( !PantCompFlag && ( PantVolume > 0.1 ) ) if( !PantCompFlag && ( PantVolume > 0.1 ) )
PantVolume -= dt * 0.0003 * std::max( 1.0, PantPress * 0.5 ); // nieszczelności: 0.0003=0.3l/s PantVolume -= dt * 0.0003 * std::max( 1.0, PantPress * 0.5 ); // nieszczelności: 0.0003=0.3l/s
/*
// NOTE: disabled as this is redundant with check done in dynobj.update() if( PantPress < EnginePowerSource.CollectorParameters.MinPress ) {
// TODO: determine if this isn't a mistake -- // 3.5 wg http://www.transportszynowy.pl/eu06-07pneumat.php
// though unlikely it's possible this is emulation of a different circuit than the pantograph pressure switch, with similar function? if( true == PantPressSwitchActive ) {
// TBD, TODO: alternatively, move the dynobj.update() subroutine here, as it doesn't touch elements outside of the mover object // opuszczenie pantografów przy niskim ciśnieniu
if( Mains ) { if( TrainType != dt_EZT ) {
// nie wchodzić w funkcję bez potrzeby // pressure switch safety measure -- open the line breaker, unless there's alternate source of traction voltage
if( EngineType == ElectricSeriesMotor ) { if( GetTrainsetVoltage() < EnginePowerSource.CollectorParameters.MinV ) {
// nie dotyczy... czego właściwie? // TODO: check whether line breaker should be open EMU-wide
if( ( true == PantPressSwitchActive ) MainSwitch( false, ( TrainType == dt_EZT ? range_t::unit : range_t::local ) );
&& ( PantPress < EnginePowerSource.CollectorParameters.MinPress ) ) {
// wywalenie szybkiego z powodu niskiego ciśnienia
if( GetTrainsetVoltage() < 0.5 * EnginePowerSource.MaxVoltage ) {
// to jest trochę proteza; zasilanie członu może być przez sprzęg WN
if( MainSwitch( false, ( TrainType == dt_EZT ? range::unit : range::local ) ) ) {
EventFlag = true;
}
} }
}
else {
// specialized variant for EMU -- pwr system disables converter and heating,
// and prevents their activation until pressure switch is set again
PantPressLockActive = true;
// TODO: separate 'heating allowed' from actual heating flag, so we can disable it here without messing up heating toggle
ConverterSwitch( false, range_t::unit );
}
// mark the pressure switch as spent
PantPressSwitchActive = false;
}
}
else {
if( PantPress >= 4.6 ) {
// NOTE: we require active low power source to prime the pressure switch
// this is a work-around for potential isssues caused by the switch activating on otherwise idle vehicles, but should check whether it's accurate
if( ( true == Battery )
|| ( true == ConverterFlag ) ) {
// prime the pressure switch
PantPressSwitchActive = true;
// turn off the subsystems lock
PantPressLockActive = false;
}
// NOTE: disabled, the flag gets set in dynobj.update() when the pantograph actually drops if( PantPress >= 4.8 ) {
// mark the pressure switch as spent, regardless whether line breaker actually opened // Winger - automatyczne wylaczanie malej sprezarki
PantPressSwitchActive = false; // TODO: governor lock, disables usage until pressure drop below 3.8 (should really make compressor object we could reuse)
PantCompFlag = false;
} }
} }
} }
*/
/* /*
// NOTE: pantograph tank pressure sharing experimentally disabled for more accurate simulation // NOTE: pantograph tank pressure sharing experimentally disabled for more accurate simulation
if (TrainType != dt_EZT) // w EN57 pompuje się tylko w silnikowym if (TrainType != dt_EZT) // w EN57 pompuje się tylko w silnikowym
@@ -1351,9 +1367,6 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
} // liczone dL, predkosc i przyspieszenie } // liczone dL, predkosc i przyspieszenie
if (Power > 1.0) // w rozrządczym nie (jest błąd w FIZ!) - Ra 2014-07: teraz we wszystkich
UpdatePantVolume(dt); // Ra 2014-07: obsługa zbiornika rozrządu oraz pantografów
auto const d { ( auto const d { (
EngineType == TEngineType::WheelsDriven ? EngineType == TEngineType::WheelsDriven ?
dL * CabNo : // na chwile dla testu dL * CabNo : // na chwile dla testu
@@ -1364,6 +1377,7 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
// koniec procedury, tu nastepuja dodatkowe procedury pomocnicze // koniec procedury, tu nastepuja dodatkowe procedury pomocnicze
compute_movement_( dt ); compute_movement_( dt );
// security system // security system
if (!DebugModeFlag) if (!DebugModeFlag)
SecuritySystemCheck(dt1); SecuritySystemCheck(dt1);
@@ -1430,9 +1444,6 @@ double TMoverParameters::FastComputeMovement(double dt, const TTrackShape &Shape
if (Couplers[b].CheckCollision) if (Couplers[b].CheckCollision)
CollisionDetect(b, dt); // zmienia niejawnie AccS, V !!! CollisionDetect(b, dt); // zmienia niejawnie AccS, V !!!
} // liczone dL, predkosc i przyspieszenie } // liczone dL, predkosc i przyspieszenie
// QQQ
if (Power > 1.0) // w rozrządczym nie (jest błąd w FIZ!)
UpdatePantVolume(dt); // Ra 2014-07: obsługa zbiornika rozrządu oraz pantografów
auto const d { ( auto const d { (
EngineType == TEngineType::WheelsDriven ? EngineType == TEngineType::WheelsDriven ?
@@ -1482,6 +1493,11 @@ void TMoverParameters::compute_movement_( double const Deltatime ) {
// sprężarka musi mieć jakąś niezerową wydajność żeby rozważać jej załączenie i pracę // sprężarka musi mieć jakąś niezerową wydajność żeby rozważać jej załączenie i pracę
CompressorCheck( Deltatime ); CompressorCheck( Deltatime );
} }
if( Power > 1.0 ) {
// w rozrządczym nie (jest błąd w FIZ!) - Ra 2014-07: teraz we wszystkich
UpdatePantVolume( Deltatime ); // Ra 2014-07: obsługa zbiornika rozrządu oraz pantografów
}
UpdateBrakePressure(Deltatime); UpdateBrakePressure(Deltatime);
UpdatePipePressure(Deltatime); UpdatePipePressure(Deltatime);
UpdateBatteryVoltage(Deltatime); UpdateBatteryVoltage(Deltatime);
@@ -2695,61 +2711,21 @@ bool TMoverParameters::IncBrakeLevelOld(void)
{ {
bool IBLO = false; bool IBLO = false;
if ((BrakeCtrlPosNo > 0) /*and (LocalBrakePos=0)*/) if (BrakeCtrlPosNo > 0)
{ {
if (BrakeCtrlPos < BrakeCtrlPosNo) if (BrakeCtrlPos < BrakeCtrlPosNo)
{ {
BrakeCtrlPos++; ++BrakeCtrlPos;
// BrakeCtrlPosR = BrakeCtrlPos;
// youBy: wywalilem to, jak jest EP, to sa przenoszone sygnaly nt. co ma robic, a nie
// poszczegolne pozycje;
// wystarczy spojrzec na Knorra i Oerlikona EP w EN57; mogly ze soba
// wspolapracowac
//{
// if (BrakeSystem==ElectroPneumatic)
// if (BrakePressureActual.BrakeType==ElectroPneumatic)
// {
// BrakeStatus = ord(BrakeCtrlPos > 0);
// SendCtrlToNext("BrakeCtrl", BrakeCtrlPos, CabNo);
// }
// else SendCtrlToNext("BrakeCtrl", -2, CabNo);
// else
// if (!TestFlag(BrakeStatus,b_dmg))
// BrakeStatus = b_on;}
// youBy: EP po nowemu // youBy: EP po nowemu
IBLO = true; IBLO = true;
if ((BrakePressureActual.PipePressureVal < 0) && if ((BrakePressureActual.PipePressureVal < 0) &&
(BrakePressureTable[BrakeCtrlPos - 1].PipePressureVal > 0)) (BrakePressureTable[BrakeCtrlPos - 1].PipePressureVal > 0))
LimPipePress = PipePress; LimPipePress = PipePress;
//ten kawałek jest bez sensu gdyż nic nie robił. Zakomntowałem. GF 20161124
//if (BrakeSystem == ElectroPneumatic)
// if (BrakeSubsystem != ss_K)
// {
// if ((BrakeCtrlPos * BrakeCtrlPos) == 1)
// {
// // SendCtrlToNext('Brake',BrakeCtrlPos,CabNo);
// // SetFlag(BrakeStatus,b_epused);
// }
// else
// {
// // SendCtrlToNext('Brake',0,CabNo);
// // SetFlag(BrakeStatus,-b_epused);
// }
// }
} }
else else {
{
IBLO = false; IBLO = false;
// if (BrakeSystem == Pneumatic)
// EmergencyBrakeSwitch(true);
} }
} }
else
IBLO = false;
return IBLO; return IBLO;
} }
@@ -2762,69 +2738,20 @@ bool TMoverParameters::DecBrakeLevelOld(void)
{ {
bool DBLO = false; bool DBLO = false;
if ((BrakeCtrlPosNo > 0) /*&& (LocalBrakePos == 0)*/) if (BrakeCtrlPosNo > 0)
{ {
if (BrakeCtrlPos > -1 - int(BrakeHandle == TBrakeHandle::FV4a)) if (BrakeCtrlPos > ( ( BrakeHandle == TBrakeHandle::FV4a ) ? -2 : -1 ) )
{ {
BrakeCtrlPos--; --BrakeCtrlPos;
// BrakeCtrlPosR:=BrakeCtrlPos;
//if (EmergencyBrakeFlag)
//{
// EmergencyBrakeFlag = false; //!!!
// SendCtrlToNext("Emergency_brake", 0, CabNo);
//}
// youBy: wywalilem to, jak jest EP, to sa przenoszone sygnaly nt. co ma robic, a nie
// poszczegolne pozycje;
// wystarczy spojrzec na Knorra i Oerlikona EP w EN57; mogly ze soba
// wspolapracowac
/*
if (BrakeSystem == ElectroPneumatic)
if (BrakePressureActual.BrakeType == ElectroPneumatic)
{
// BrakeStatus =ord(BrakeCtrlPos > 0);
SendCtrlToNext("BrakeCtrl",BrakeCtrlPos,CabNo);
}
else SendCtrlToNext('BrakeCtrl',-2,CabNo);
// else}
// if (not TestFlag(BrakeStatus,b_dmg) and (not
TestFlag(BrakeStatus,b_release))) then
// BrakeStatus:=b_off; {luzowanie jesli dziala oraz nie byl wlaczony
odluzniacz
*/
// youBy: EP po nowemu // youBy: EP po nowemu
DBLO = true; DBLO = true;
// if ((BrakePressureTable[BrakeCtrlPos].PipePressureVal<0.0) && // if ((BrakePressureTable[BrakeCtrlPos].PipePressureVal<0.0) &&
// (BrakePressureTable[BrakeCtrlPos+1].PipePressureVal > 0)) // (BrakePressureTable[BrakeCtrlPos+1].PipePressureVal > 0))
// LimPipePress:=PipePress; // LimPipePress=PipePress;
// to nic nie robi. Zakomentowałem. GF 20161124
//if (BrakeSystem == ElectroPneumatic)
// if (BrakeSubsystem != ss_K)
// {
// if ((BrakeCtrlPos * BrakeCtrlPos) == 1)
// {
// // SendCtrlToNext("Brake", BrakeCtrlPos, CabNo);
// // SetFlag(BrakeStatus, b_epused);
// }
// else
// {
// // SendCtrlToNext("Brake", 0, CabNo);
// // SetFlag(BrakeStatus, -b_epused);
// }
// }
// for b:=0 to 1 do {poprawic to!}
// with Couplers[b] do
// if CouplingFlag and ctrain_controll=ctrain_controll then
// Connected^.BrakeCtrlPos:=BrakeCtrlPos;
//
} }
else else
DBLO = false; DBLO = false;
} }
else
DBLO = false;
return DBLO; return DBLO;
} }

View File

@@ -1409,7 +1409,10 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
case tt_Switch: // dla zwrotnicy dwa razy szyny case tt_Switch: // dla zwrotnicy dwa razy szyny
if( m_material1 || m_material2 ) { if( m_material1 || m_material2 ) {
// iglice liczone tylko dla zwrotnic // iglice liczone tylko dla zwrotnic
gfx::basic_vertex rpts3[24], rpts4[24]; gfx::basic_vertex
rpts3[24],
rpts4[24];
glm::vec3 const flipxvalue { -1, 1, 1 };
for( int i = 0; i < 12; ++i ) { for( int i = 0; i < 12; ++i ) {
rpts3[ i ] = { rpts3[ i ] = {
@@ -1428,17 +1431,17 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
{ ( -fHTW - iglica[ i ].position.x ) * cos1 + iglica[ i ].position.y * sin1, { ( -fHTW - iglica[ i ].position.x ) * cos1 + iglica[ i ].position.y * sin1,
-( -fHTW - iglica[ i ].position.x ) * sin1 + iglica[ i ].position.y * cos1, -( -fHTW - iglica[ i ].position.x ) * sin1 + iglica[ i ].position.y * cos1,
0.f}, 0.f},
{iglica[ i ].normal}, {iglica[ i ].normal * flipxvalue},
{iglica[ i ].texture.x, 0.f} }; {iglica[ i ].texture.x, 0.f} };
rpts4[ 23 - i ] = { rpts4[ 23 - i ] = {
{ ( -fHTW2 - szyna[ i ].position.x ) * cos2 + szyna[ i ].position.y * sin2, { ( -fHTW2 - szyna[ i ].position.x ) * cos2 + szyna[ i ].position.y * sin2,
-( -fHTW2 - szyna[ i ].position.x ) * sin2 + iglica[ i ].position.y * cos2, -( -fHTW2 - szyna[ i ].position.x ) * sin2 + iglica[ i ].position.y * cos2,
0.f}, 0.f},
{szyna[ i ].normal}, {szyna[ i ].normal * flipxvalue},
{szyna[ i ].texture.x, 0.f} }; {szyna[ i ].texture.x, 0.f} };
} }
// TODO, TBD: change all track geometry to triangles, to allow packing data in less, larger buffers // TODO, TBD: change all track geometry to triangles, to allow packing data in less, larger buffers
auto const bladelength { 2 * Global.SplineFidelity }; auto const bladelength { static_cast<int>( std::ceil( SwitchExtension->Segments[ 0 ]->RaSegCount() * 0.65 ) ) };
if (SwitchExtension->RightSwitch) if (SwitchExtension->RightSwitch)
{ // nowa wersja z SPKS, ale odwrotnie lewa/prawa { // nowa wersja z SPKS, ale odwrotnie lewa/prawa
gfx::vertex_array vertices; gfx::vertex_array vertices;
@@ -2464,6 +2467,7 @@ TTrack * TTrack::RaAnimate()
gfx::basic_vertex gfx::basic_vertex
rpts3[ 24 ], rpts3[ 24 ],
rpts4[ 24 ]; rpts4[ 24 ];
glm::vec3 const flipxvalue { -1, 1, 1 };
for (int i = 0; i < 12; ++i) { for (int i = 0; i < 12; ++i) {
rpts3[ i ] = { rpts3[ i ] = {
@@ -2482,19 +2486,18 @@ TTrack * TTrack::RaAnimate()
{+( -fHTW - iglica[ i ].position.x ) * cos1 + iglica[ i ].position.y * sin1, {+( -fHTW - iglica[ i ].position.x ) * cos1 + iglica[ i ].position.y * sin1,
-( -fHTW - iglica[ i ].position.x ) * sin1 + iglica[ i ].position.y * cos1, -( -fHTW - iglica[ i ].position.x ) * sin1 + iglica[ i ].position.y * cos1,
0.f}, 0.f},
{iglica[ i ].normal}, {iglica[ i ].normal * flipxvalue},
{iglica[ i ].texture.x, 0.f} }; {iglica[ i ].texture.x, 0.f} };
rpts4[ 23 - i ] = { rpts4[ 23 - i ] = {
{ ( -fHTW2 - szyna[ i ].position.x ) * cos2 + szyna[ i ].position.y * sin2, { ( -fHTW2 - szyna[ i ].position.x ) * cos2 + szyna[ i ].position.y * sin2,
-( -fHTW2 - szyna[ i ].position.x ) * sin2 + iglica[ i ].position.y * cos2, -( -fHTW2 - szyna[ i ].position.x ) * sin2 + iglica[ i ].position.y * cos2,
0.f}, 0.f},
{szyna[ i ].normal}, {szyna[ i ].normal * flipxvalue},
{szyna[ i ].texture.x, 0.f} }; {szyna[ i ].texture.x, 0.f} };
} }
gfx::vertex_array vertices; gfx::vertex_array vertices;
auto const bladelength { static_cast<int>( std::ceil( SwitchExtension->Segments[ 0 ]->RaSegCount() * 0.65 ) ) };
auto const bladelength { 2 * Global.SplineFidelity };
if (SwitchExtension->RightSwitch) if (SwitchExtension->RightSwitch)
{ // nowa wersja z SPKS, ale odwrotnie lewa/prawa { // nowa wersja z SPKS, ale odwrotnie lewa/prawa
if( m_material1 ) { if( m_material1 ) {

View File

@@ -4832,8 +4832,8 @@ bool TTrain::Update( double const Deltatime )
// hunter-080812: wyrzucanie szybkiego na elektrykach gdy nie ma napiecia przy dowolnym ustawieniu kierunkowego // hunter-080812: wyrzucanie szybkiego na elektrykach gdy nie ma napiecia przy dowolnym ustawieniu kierunkowego
// Ra: to już jest w T_MoverParameters::TractionForce(), ale zależy od kierunku // Ra: to już jest w T_MoverParameters::TractionForce(), ale zależy od kierunku
if( ( mvControlled->Mains ) if( ( mvControlled->Mains )
&& ( mvControlled->EngineType == TEngineType::ElectricSeriesMotor ) ) { && ( mvControlled->EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) ) {
if( std::max( mvControlled->GetTrainsetVoltage(), std::fabs( mvControlled->RunningTraction.TractionVoltage ) ) < 0.5 * mvControlled->EnginePowerSource.MaxVoltage ) { if( std::max( mvControlled->GetTrainsetVoltage(), std::abs( mvControlled->RunningTraction.TractionVoltage ) ) < 0.5 * mvControlled->EnginePowerSource.MaxVoltage ) {
// TODO: check whether it should affect entire consist for EMU // TODO: check whether it should affect entire consist for EMU
// TODO: check whether it should happen if there's power supplied alternatively through hvcouplers // TODO: check whether it should happen if there's power supplied alternatively through hvcouplers
// TODO: potentially move this to the mover module, as there isn't much reason to have this dependent on the operator presence // TODO: potentially move this to the mover module, as there isn't much reason to have this dependent on the operator presence
@@ -5627,24 +5627,28 @@ bool TTrain::Update( double const Deltatime )
} }
case 1: { case 1: {
//światło wewnętrzne przygaszone (255 216 176) //światło wewnętrzne przygaszone (255 216 176)
if( mvOccupied->ConverterFlag == true ) { auto const converteractive { (
// jasnosc dla zalaczonej przetwornicy ( mvOccupied->ConverterFlag )
DynamicObject->InteriorLightLevel = 0.4f; || ( ( ( mvOccupied->Couplers[ side::front ].CouplingFlag & coupling::permanent ) != 0 ) && mvOccupied->Couplers[ side::front ].Connected->ConverterFlag )
} || ( ( ( mvOccupied->Couplers[ side::rear ].CouplingFlag & coupling::permanent ) != 0 ) && mvOccupied->Couplers[ side::rear ].Connected->ConverterFlag ) ) };
else {
DynamicObject->InteriorLightLevel = 0.2f; DynamicObject->InteriorLightLevel = (
} converteractive ?
0.4f :
0.2f );
break; break;
} }
case 2: { case 2: {
//światło wewnętrzne zapalone (255 216 176) //światło wewnętrzne zapalone (255 216 176)
if( mvOccupied->ConverterFlag == true ) { auto const converteractive { (
// jasnosc dla zalaczonej przetwornicy ( mvOccupied->ConverterFlag )
DynamicObject->InteriorLightLevel = 1.0f; || ( ( ( mvOccupied->Couplers[ side::front ].CouplingFlag & coupling::permanent ) != 0 ) && mvOccupied->Couplers[ side::front ].Connected->ConverterFlag )
} || ( ( ( mvOccupied->Couplers[ side::rear ].CouplingFlag & coupling::permanent ) != 0 ) && mvOccupied->Couplers[ side::rear ].Connected->ConverterFlag ) ) };
else {
DynamicObject->InteriorLightLevel = 0.5f; DynamicObject->InteriorLightLevel = (
} converteractive ?
1.0f :
0.5f );
break; break;
} }
} }

View File

@@ -95,6 +95,11 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
{ // przesuwanie wózka po torach o odległość (fDistance), z wyzwoleniem eventów { // przesuwanie wózka po torach o odległość (fDistance), z wyzwoleniem eventów
// bPrimary=true - jest pierwszą osią w pojeździe, czyli generuje eventy i przepisuje pojazd // bPrimary=true - jest pierwszą osią w pojeździe, czyli generuje eventy i przepisuje pojazd
// Ra: zwraca false, jeśli pojazd ma być usunięty // Ra: zwraca false, jeśli pojazd ma być usunięty
auto const ismoving { ( std::abs( fDistance ) > 0.01 ) && ( Owner->GetVelocity() > 0.01 ) };
int const eventfilter { (
( ( true == ismoving ) && ( Owner->ctOwner != nullptr ) ) ?
Owner->ctOwner->Direction() * ( Owner->ctOwner->Vehicle()->DirectionGet() == Owner->DirectionGet() ? 1 : -1 ) * ( fDirection > 0 ? 1 : -1 ) :
0 ) };
fDistance *= fDirection; // dystans mnożnony przez kierunek fDistance *= fDirection; // dystans mnożnony przez kierunek
double s; // roboczy dystans double s; // roboczy dystans
double dir; // zapamiętany kierunek do sprawdzenia, czy się zmienił double dir; // zapamiętany kierunek do sprawdzenia, czy się zmienił
@@ -105,8 +110,7 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
// TODO: refactor following block as track method // TODO: refactor following block as track method
if( pCurrentTrack->m_events ) { // sumaryczna informacja o eventach if( pCurrentTrack->m_events ) { // sumaryczna informacja o eventach
// omijamy cały ten blok, gdy tor nie ma on żadnych eventów (większość nie ma) // omijamy cały ten blok, gdy tor nie ma on żadnych eventów (większość nie ma)
if( ( std::abs( fDistance ) < 0.01 ) if( false == ismoving ) {
&& ( Owner->GetVelocity() < 0.01 ) ) {
//McZapkie-140602: wyzwalanie zdarzenia gdy pojazd stoi //McZapkie-140602: wyzwalanie zdarzenia gdy pojazd stoi
if( ( Owner->Mechanik != nullptr ) if( ( Owner->Mechanik != nullptr )
&& ( Owner->Mechanik->Primary() ) ) { && ( Owner->Mechanik->Primary() ) ) {
@@ -115,7 +119,7 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
} }
pCurrentTrack->QueueEvents( pCurrentTrack->m_events0all, Owner ); pCurrentTrack->QueueEvents( pCurrentTrack->m_events0all, Owner );
} }
else if (fDistance < 0) { else if( (fDistance < 0) && ( eventfilter < 0 ) ) {
// event1, eventall1 // event1, eventall1
if( SetFlag( iEventFlag, -1 ) ) { if( SetFlag( iEventFlag, -1 ) ) {
// zawsze zeruje flagę sprawdzenia, jak mechanik dosiądzie, to się nie wykona // zawsze zeruje flagę sprawdzenia, jak mechanik dosiądzie, to się nie wykona
@@ -135,7 +139,7 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
} }
} }
} }
else if (fDistance > 0) { else if( ( fDistance > 0 ) && ( eventfilter > 0 ) ) {
// event2, eventall2 // event2, eventall2
if( SetFlag( iEventFlag, -2 ) ) { if( SetFlag( iEventFlag, -2 ) ) {
// zawsze ustawia flagę sprawdzenia, jak mechanik dosiądzie, to się nie wykona // zawsze ustawia flagę sprawdzenia, jak mechanik dosiądzie, to się nie wykona

View File

@@ -55,14 +55,16 @@ opengl_material::deserialize_mapping( cParser &Input, int const Priority, bool c
; // all work is done in the header ; // all work is done in the header
} }
} }
else if( key == "texture1:" ) { else if( ( key == "texture1:" )
|| ( key == "texture_diffuse:" ) ) {
if( ( texture1 == null_handle ) if( ( texture1 == null_handle )
|| ( Priority > priority1 ) ) { || ( Priority > priority1 ) ) {
texture1 = GfxRenderer.Fetch_Texture( value, Loadnow ); texture1 = GfxRenderer.Fetch_Texture( value, Loadnow );
priority1 = Priority; priority1 = Priority;
} }
} }
else if( key == "texture2:" ) { else if( ( key == "texture2:" )
|| ( key == "texture_normalmap:" ) ) {
if( ( texture2 == null_handle ) if( ( texture2 == null_handle )
|| ( Priority > priority2 ) ) { || ( Priority > priority2 ) ) {
texture2 = GfxRenderer.Fetch_Texture( value, Loadnow ); texture2 = GfxRenderer.Fetch_Texture( value, Loadnow );