16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-23 14:29:18 +02:00

ai braking test, motor overload relay threshold logic enhancement, vehicle max load parameter

This commit is contained in:
tmj-fstate
2021-06-05 21:30:53 +02:00
parent 7b816594ba
commit 2e86b3a5e9
11 changed files with 472 additions and 169 deletions

View File

@@ -885,7 +885,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
IsScheduledPassengerStopVisible = false; IsScheduledPassengerStopVisible = false;
mvOccupied->SecuritySystem.SHPLock = false; mvOccupied->SecuritySystem.SHPLock = false;
// te flagi są ustawiane tutaj, w razie potrzeby // te flagi są ustawiane tutaj, w razie potrzeby
iDrivigFlags &= ~(moveTrackEnd | moveSwitchFound | moveSemaphorFound | /*moveSpeedLimitFound*/ moveStopPointFound ); iDrivigFlags &= ~(moveTrackEnd | moveSwitchFound | moveSignalFound | /*moveSpeedLimitFound*/ moveStopPointFound );
for( std::size_t idx = 0; idx < sSpeedTable.size(); ++idx ) { for( std::size_t idx = 0; idx < sSpeedTable.size(); ++idx ) {
// o ile dana pozycja tabelki jest istotna // o ile dana pozycja tabelki jest istotna
@@ -1064,7 +1064,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// jeśli mieliśmy ograniczenie z semafora i nie ma przed nami // jeśli mieliśmy ograniczenie z semafora i nie ma przed nami
if( ( VelSignalLast >= 0.0 ) if( ( VelSignalLast >= 0.0 )
&& ( ( iDrivigFlags & ( moveSemaphorFound | moveSwitchFound | moveStopPointFound ) ) == 0 ) && ( ( iDrivigFlags & ( moveSignalFound | moveSwitchFound | moveStopPointFound ) ) == 0 )
&& ( true == TestFlag( OrderCurrentGet(), Obey_train ) ) ) { && ( true == TestFlag( OrderCurrentGet(), Obey_train ) ) ) {
VelSignalLast = -1.0; VelSignalLast = -1.0;
} }
@@ -1557,7 +1557,7 @@ TController::TableUpdateEvent( double &Velocity, TCommandType &Command, TSpeedPo
} }
else { else {
//jeśli z przodu to dajemy flagę, że jest //jeśli z przodu to dajemy flagę, że jest
iDrivigFlags |= moveSemaphorFound; iDrivigFlags |= moveSignalFound;
Signaldistance = std::min( Point.fDist, Signaldistance ); Signaldistance = std::min( Point.fDist, Signaldistance );
// if there's another vehicle closer to the signal, then it's likely its intended recipient // if there's another vehicle closer to the signal, then it's likely its intended recipient
// HACK: if so, make it a stop point, to prevent non-signals farther down affect us // HACK: if so, make it a stop point, to prevent non-signals farther down affect us
@@ -1854,23 +1854,23 @@ void TController::TableSort() {
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche, bool primary) :// czy ma aktywnie prowadzić? TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche, bool Primary) :// czy ma aktywnie prowadzić?
AIControllFlag( AI ), pVehicle( NewControll ) AIControllFlag( AI ), pVehicle( NewControll )
{ {
ControllingSet(); // utworzenie połączenia do sterowanego pojazdu
if( pVehicle != nullptr ) { if( pVehicle != nullptr ) {
pVehicles[ 0 ] = pVehicle->GetFirstDynamic( 0 ); // pierwszy w kierunku jazdy (Np. Pc1) pVehicles[ end::front ] = pVehicle->GetFirstDynamic( end::front ); // pierwszy w kierunku jazdy (Np. Pc1)
pVehicles[ 1 ] = pVehicle->GetFirstDynamic( 1 ); // ostatni w kierunku jazdy (końcówki) pVehicles[ end::rear ] = pVehicle->GetFirstDynamic( end::rear ); // ostatni w kierunku jazdy (końcówki)
} }
else { else {
pVehicles[ 0 ] = nullptr; pVehicles[ end::front ] = nullptr;
pVehicles[ 1 ] = nullptr; pVehicles[ end::rear ] = nullptr;
} }
ControllingSet(); // utworzenie połączenia do sterowanego pojazdu
if( mvOccupied != nullptr ) { if( mvOccupied != nullptr ) {
iDirectionOrder = mvOccupied->CabActive; // 1=do przodu (w kierunku sprzęgu 0) iDirectionOrder = mvOccupied->CabActive; // 1=do przodu (w kierunku sprzęgu 0)
VehicleName = mvOccupied->Name; VehicleName = mvOccupied->Name;
if( mvOccupied->CategoryFlag & 2 ) { // samochody: na podst. http://www.prawko-kwartnik.info/hamowanie.html if( is_car() ) { // samochody: na podst. http://www.prawko-kwartnik.info/hamowanie.html
// fDriverBraking=0.0065; //mnożone przez (v^2+40*v) [km/h] daje prawie drogę hamowania [m] // fDriverBraking=0.0065; //mnożone przez (v^2+40*v) [km/h] daje prawie drogę hamowania [m]
fDriverBraking = 0.03; // coś nie hamują te samochody zbyt dobrze fDriverBraking = 0.03; // coś nie hamują te samochody zbyt dobrze
fDriverDist = 5.0; // 5m - zachowywany odstęp przed kolizją fDriverDist = 5.0; // 5m - zachowywany odstęp przed kolizją
@@ -1907,7 +1907,7 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche,
// OrderValue=0; // OrderValue=0;
OrdersClear(); OrdersClear();
if( true == primary ) { if( true == Primary ) {
iDrivigFlags |= movePrimary; // aktywnie prowadzące pojazd iDrivigFlags |= movePrimary; // aktywnie prowadzące pojazd
} }
@@ -2105,8 +2105,8 @@ void TController::Activation()
{ // jeśli zmieniony został pojazd prowadzony { // jeśli zmieniony został pojazd prowadzony
ControllingSet(); // utworzenie połączenia do sterowanego pojazdu (może się zmienić) - silnikowy dla EZT ControllingSet(); // utworzenie połączenia do sterowanego pojazdu (może się zmienić) - silnikowy dla EZT
if( ( mvOccupied->BrakeCtrlPosNo > 0 ) if( ( mvOccupied->BrakeCtrlPosNo > 0 )
&& ( ( mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic ) && ( ( BrakeSystem == TBrakeSystem::Pneumatic )
|| ( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) ) ) { || ( BrakeSystem == TBrakeSystem::ElectroPneumatic ) ) ) {
mvOccupied->LimPipePress = mvOccupied->PipePress; mvOccupied->LimPipePress = mvOccupied->PipePress;
mvOccupied->ActFlowSpeed = 0; mvOccupied->ActFlowSpeed = 0;
} }
@@ -2242,6 +2242,7 @@ void TController::AutoRewident()
} }
// potentially release manual brake // potentially release manual brake
d->MoverParameters->DecManualBrakeLevel( ManualBrakePosNo ); d->MoverParameters->DecManualBrakeLevel( ManualBrakePosNo );
d->MoverParameters->SpringBrake.Activate = false;
} }
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)
} }
@@ -2276,6 +2277,9 @@ void TController::AutoRewident()
fNominalAccThreshold = fAccThreshold; fNominalAccThreshold = fAccThreshold;
} }
BrakeSystem = consist_brake_system();
mvOccupied->EpFuseSwitch( BrakeSystem == TBrakeSystem::ElectroPneumatic );
if( OrderCurrentGet() & ( Obey_train | Bank ) ) { if( OrderCurrentGet() & ( Obey_train | Bank ) ) {
// 4. Przeliczanie siły hamowania // 4. Przeliczanie siły hamowania
double const velstep = ( mvOccupied->Vmax*0.5 ) / BrakeAccTableSize; double const velstep = ( mvOccupied->Vmax*0.5 ) / BrakeAccTableSize;
@@ -2310,12 +2314,13 @@ void TController::AutoRewident()
0.25 ); 0.25 );
if( is_emu() ) { if( is_emu() ) {
auto ep_factor { ( BrakeSystem == TBrakeSystem::ElectroPneumatic ? 8 : 4 ) };
if( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) { if( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) {
// HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors // HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors
fNominalAccThreshold = std::max( -0.60, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] ); fNominalAccThreshold = std::max( -0.60, -fBrake_a0[ BrakeAccTableSize ] - ep_factor * fBrake_a1[ BrakeAccTableSize ] );
} }
else { else {
fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] ); fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - ep_factor * fBrake_a1[ BrakeAccTableSize ] );
} }
fBrakeReaction = 0.25; fBrakeReaction = 0.25;
} }
@@ -2503,6 +2508,18 @@ bool TController::CheckVehicles(TOrders user)
} }
} }
// kasowanie pamieci hamowania kontrolnego
if (OrderCurrentGet() & (Shunt | Loose_shunt | Disconnect | Connect | Change_direction)) {
DynamicBrakeTest = 0;
DBT_VelocityBrake
= DBT_VelocityRelease
= DBT_VelocityFinish
= DBT_BrakingTime
= DBT_ReleasingTime
= DBT_MidPointAcc
= 0;
}
// HACK: ensure vehicle lights are active from the beginning, if it had pre-activated battery // HACK: ensure vehicle lights are active from the beginning, if it had pre-activated battery
if( mvOccupied->LightsPosNo > 0 ) { if( mvOccupied->LightsPosNo > 0 ) {
pVehicle->SetLights(); pVehicle->SetLights();
@@ -2608,6 +2625,31 @@ void TController::DirectionChange() {
} }
} }
TBrakeSystem TController::consist_brake_system() const {
if( mvOccupied->BrakeSystem != TBrakeSystem::ElectroPneumatic ) { return mvOccupied->BrakeSystem; }
auto isepcapable = true;
if( pVehicles[ end::front ] != pVehicles[ end::rear ] ) {
// more detailed version, will use manual braking also for coupled sets of controlled vehicles
auto *vehicle = pVehicles[ end::front ]; // start from first
while( ( true == isepcapable )
&& ( vehicle != nullptr ) ) {
// NOTE: we could simplify this by doing only check of the rear coupler, but this can be quite tricky in itself
// TODO: add easier ways to access front/rear coupler taking into account vehicle's direction
isepcapable = (
( ( vehicle->MoverParameters->Couplers[ end::front ].Connected == nullptr )
|| ( ( vehicle->MoverParameters->Couplers[ end::front ].CouplingFlag & coupling::control )
&& ( vehicle->MoverParameters->Couplers[ end::front ].Connected->Power > -1 ) ) )
&& ( ( vehicle->MoverParameters->Couplers[ end::rear ].Connected == nullptr )
|| ( ( vehicle->MoverParameters->Couplers[ end::rear ].CouplingFlag & coupling::control )
&& ( vehicle->MoverParameters->Couplers[ end::rear ].Connected->Power > -1 ) ) ) );
vehicle = vehicle->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła)
}
}
return ( isepcapable ? TBrakeSystem::ElectroPneumatic : TBrakeSystem::Pneumatic );
}
int TController::OrderDirectionChange(int newdir, TMoverParameters *Vehicle) int TController::OrderDirectionChange(int newdir, TMoverParameters *Vehicle)
{ // zmiana kierunku jazdy, niezależnie od kabiny { // zmiana kierunku jazdy, niezależnie od kabiny
int testd = newdir; int testd = newdir;
@@ -2961,8 +3003,12 @@ bool TController::ReleaseEngine() {
bool TController::IncBrake() bool TController::IncBrake()
{ // zwiększenie hamowania { // zwiększenie hamowania
bool OK = false; auto OK { false };
switch( mvOccupied->BrakeSystem ) { auto const bs {
( ( BrakeSystem == TBrakeSystem::ElectroPneumatic ) && ( ForcePNBrake ) ) ?
TBrakeSystem::Pneumatic :
BrakeSystem };
switch( bs ) {
case TBrakeSystem::Individual: { case TBrakeSystem::Individual: {
if( mvOccupied->LocalBrake == TLocalBrake::ManualBrake ) { if( mvOccupied->LocalBrake == TLocalBrake::ManualBrake ) {
OK = mvOccupied->IncManualBrakeLevel( 1 + static_cast<int>( std::floor( 0.5 + std::fabs( AccDesired ) ) ) ); OK = mvOccupied->IncManualBrakeLevel( 1 + static_cast<int>( std::floor( 0.5 + std::fabs( AccDesired ) ) ) );
@@ -2973,8 +3019,15 @@ bool TController::IncBrake()
break; break;
} }
case TBrakeSystem::Pneumatic: { case TBrakeSystem::Pneumatic: {
if (bs != mvOccupied->BrakeSystem)
{
while (mvOccupied->BrakeOpModeFlag > bom_PN)
{
mvOccupied->BrakeOpModeFlag >>= 1;
}
}
// NOTE: can't perform just test whether connected vehicle == nullptr, due to virtual couplers formed with nearby vehicles // NOTE: can't perform just test whether connected vehicle == nullptr, due to virtual couplers formed with nearby vehicles
bool standalone { true }; auto standalone { true };
if( ( mvOccupied->TrainType == dt_ET41 ) if( ( mvOccupied->TrainType == dt_ET41 )
|| ( mvOccupied->TrainType == dt_ET42 ) ) { || ( mvOccupied->TrainType == dt_ET42 ) ) {
// NOTE: we're doing simplified checks full of presuptions here. // NOTE: we're doing simplified checks full of presuptions here.
@@ -3024,7 +3077,7 @@ bool TController::IncBrake()
//standalone = standalone && ( mvControlling->EIMCtrlType == 0 ); //standalone = standalone && ( mvControlling->EIMCtrlType == 0 );
if( true == standalone ) { if( ( true == standalone ) && ( false == ForcePNBrake ) ) {
if( mvControlling->EIMCtrlType > 0 ) { if( mvControlling->EIMCtrlType > 0 ) {
OK = IncBrakeEIM(); OK = IncBrakeEIM();
} }
@@ -3101,6 +3154,9 @@ bool TController::IncBrake()
break; break;
} }
case TBrakeSystem::ElectroPneumatic: { case TBrakeSystem::ElectroPneumatic: {
while( ( mvOccupied->BrakeOpModeFlag << 1 ) <= mvOccupied->BrakeOpModes ) {
mvOccupied->BrakeOpModeFlag <<= 1;
}
if( mvOccupied->EngineType == TEngineType::ElectricInductionMotor ) { if( mvOccupied->EngineType == TEngineType::ElectricInductionMotor ) {
if (mvOccupied->BrakeHandle == TBrakeHandle::MHZ_EN57) { if (mvOccupied->BrakeHandle == TBrakeHandle::MHZ_EN57) {
if (mvOccupied->BrakeCtrlPos < mvOccupied->Handle->GetPos(bh_FB)) if (mvOccupied->BrakeCtrlPos < mvOccupied->Handle->GetPos(bh_FB))
@@ -3188,8 +3244,11 @@ bool TController::IncBrakeEIM()
bool TController::DecBrake() { bool TController::DecBrake() {
auto OK { false }; auto OK { false };
auto const bs {
switch( mvOccupied->BrakeSystem ) { ( ( BrakeSystem == TBrakeSystem::ElectroPneumatic ) && ( ForcePNBrake ) ) ?
TBrakeSystem::Pneumatic :
BrakeSystem };
switch( bs ) {
case TBrakeSystem::Individual: { case TBrakeSystem::Individual: {
auto const positionchange { 1 + std::floor( 0.5 + std::abs( AccDesired ) ) }; auto const positionchange { 1 + std::floor( 0.5 + std::abs( AccDesired ) ) };
OK = ( OK = (
@@ -3357,12 +3416,24 @@ bool TController::IncSpeed()
|| (mvControlling->StLinFlag)) { // youBy polecił dodać 2012-09-08 v367 || (mvControlling->StLinFlag)) { // youBy polecił dodać 2012-09-08 v367
// 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)) {
auto const usehighoverloadrelaythreshold {
( mvControlling->TrainType != dt_ET42 ) // ET42 uses these variables for different purpose. TODO: fix this
&& ( mvControlling->ImaxHi > mvControlling->ImaxLo )
&& ( mvOccupied->Vel < ( mvControlling->IsMotorOverloadRelayHighThresholdOn() ? 30.0 : 20.0 ) )
&& ( iVehicles - ControlledEnginesCount > 0 )
// && ( std::fabs( mvControlling->Im ) > 0.85 * mvControlling->Imax )
&& ( ( mvControlling->Imax * mvControlling->EngineVoltage * ControlledEnginesCount )
/ ( fMass * (
fAccGravity == 0.025 ?
-0.01 : // prevent div/0
fAccGravity - 0.025 ) )
< -2.8 ) };
// use series mode: // use series mode:
// 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 // 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) // 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 ? 75 : 50 ) * 1000.0 }; auto const sufficienttractionforce { std::abs( mvControlling->Ft ) * ControlledEnginesCount > ( IsHeavyCargoTrain ? 75 : 50 ) * 1000.0 };
auto const sufficientacceleration { AbsAccS >= ( IsHeavyCargoTrain ? 0.03 : IsCargoTrain ? 0.06 : 0.09 ) }; auto const sufficientacceleration { AbsAccS >= ( IsHeavyCargoTrain ? 0.03 : IsCargoTrain ? 0.06 : 0.09 ) };
auto const seriesmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 ) }; 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 parallelmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 ) };
@@ -3373,6 +3444,7 @@ bool TController::IncSpeed()
( IsHeavyCargoTrain ? 0.35 : 0.40 ) ) }; ( IsHeavyCargoTrain ? 0.35 : 0.40 ) ) };
auto const useseriesmode = ( auto const useseriesmode = (
( mvControlling->Imax > mvControlling->ImaxLo ) ( mvControlling->Imax > mvControlling->ImaxLo )
|| ( true == usehighoverloadrelaythreshold )
|| ( fVoltage < useseriesmodevoltage ) || ( fVoltage < useseriesmodevoltage )
|| ( ( true == sufficientacceleration ) || ( ( true == sufficientacceleration )
&& ( true == sufficienttractionforce ) && ( true == sufficienttractionforce )
@@ -3390,6 +3462,32 @@ bool TController::IncSpeed()
mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 : mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 :
mvControlling->MainCtrlPos == mvControlling->MainCtrlPosNo ) ) ); mvControlling->MainCtrlPos == mvControlling->MainCtrlPosNo ) ) );
// if needed enable high threshold for overload relay...
if( mvControlling->TrainType != dt_ET42 ) { // ET42 uses these variables for different purpose. TODO: fix this
if( usehighoverloadrelaythreshold ) {
if( mvControlling->Imax < mvControlling->ImaxHi ) {
// to enable this setting we'll typically need the main controller in series mode (which is not guaranteed)
if( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 ) {
if( false == mvControlling->IsScndCtrlNoPowerPos() ) {
mvControlling->DecScndCtrl( 2 );
}
while( ( false == mvControlling->IsMainCtrlNoPowerPos() )
&& ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 ) ) {
mvControlling->DecMainCtrl( 1 ); // kręcimy nastawnik jazdy o 1 wstecz
}
}
mvControlling->CurrentSwitch( true ); // rozruch wysoki (za to może się ślizgać)
}
}
// ...or disable high threshold for overload relay if no longer needed
else {
if( ( mvControlling->IsMotorOverloadRelayHighThresholdOn() )
&& ( std::fabs( mvControlling->Im ) < mvControlling->ImaxLo ) ) {
mvControlling->CurrentSwitch( false ); // rozruch wysoki wyłącz
}
}
}
double Vs = 99999; double Vs = 99999;
if( usefieldshunting ? if( usefieldshunting ?
( mvControlling->ScndCtrlPos < mvControlling->ScndCtrlPosNo ) : ( mvControlling->ScndCtrlPos < mvControlling->ScndCtrlPosNo ) :
@@ -3677,21 +3775,36 @@ bool TController::IncSpeedEIM() {
bool TController::DecSpeedEIM( int const Amount ) bool TController::DecSpeedEIM( int const Amount )
{ // zmniejszenie prędkości (ale nie hamowanie) { // zmniejszenie prędkości (ale nie hamowanie)
bool OK = false; // domyślnie false, aby wyszło z pętli while bool OK = false; // domyślnie false, aby wyszło z pętli while
switch (mvControlling->EIMCtrlType) switch( mvControlling->EIMCtrlType ) {
{ case 0: {
case 0: OK = mvControlling->DecMainCtrl( Amount );
OK = mvControlling->DecMainCtrl( Amount ); break;
break; }
case 1: case 1: {
OK = mvControlling->MainCtrlPos > 4; OK = mvControlling->MainCtrlPos > 4;
if (OK) if( OK ) {
mvControlling->MainCtrlPos = 4; mvControlling->MainCtrlPos = 4;
break; }
case 2: break;
OK = mvControlling->MainCtrlPos > 2; }
if (OK) case 2: {
mvControlling->MainCtrlPos = 2; if( ( AccDesired > 0 )
break; && ( mvControlling->SpeedCtrlUnit.IsActive )
&& ( mvControlling->SpeedCtrlUnit.PowerStep > 0 )
&& ( mvControlling->SpeedCtrlUnit.DesiredPower > mvControlling->SpeedCtrlUnit.MinPower ) ) {
mvControlling->SpeedCtrlPowerDec();
}
else {
OK = mvControlling->MainCtrlPos > 2;
if( OK ) {
mvControlling->MainCtrlPos = 2;
}
}
break;
}
default: {
break;
}
} }
return OK; return OK;
} }
@@ -3785,56 +3898,51 @@ void TController::SpeedSet() {
break; break;
} }
case TEngineType::ElectricSeriesMotor: { case TEngineType::ElectricSeriesMotor: {
/*
if (Ready || (iDrivigFlags & movePress)) { // o ile może jechać if (Ready || (iDrivigFlags & movePress)) { // o ile może jechać
if (fAccGravity < -0.10) // i jedzie pod górę większą niż 10 promil // if (fAccGravity < -0.10) // i jedzie pod górę większą niż 10 promil
{ // procedura wjeżdżania na ekstremalne wzniesienia { // procedura wjeżdżania na ekstremalne wzniesienia
if (fabs(mvControlling->Im) > 0.85 * mvControlling->Imax) // a prąd jest większy niż 85% nadmiarowego if( std::fabs( mvControlling->Im ) > 0.85 * mvControlling->Imax ) { // a prąd jest większy niż 85% nadmiarowego
if (mvControlling->Imax * mvControlling->EngineVoltage / (fMass * fAccGravity) < -2.8) // a na niskim się za szybko nie pojedzie if( mvControlling->Imax * mvControlling->EngineVoltage / ( fMass * fAccGravity ) < -2.8 ) // a na niskim się za szybko nie pojedzie
{ // włączenie wysokiego rozruchu; { // włączenie wysokiego rozruchu;
// (I*U)[A*V=W=kg*m*m/sss]/(m[kg]*a[m/ss])=v[m/s]; 2.8m/ss=10km/h // (I*U)[A*V=W=kg*m*m/sss]/(m[kg]*a[m/ss])=v[m/s]; 2.8m/ss=10km/h
if (mvControlling->RList[mvControlling->MainCtrlPos].Bn > 1) if( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 ) { // jeśli jedzie na równoległym, to zbijamy do szeregowego, aby włączyć wysoki rozruch
{ // jeśli jedzie na równoległym, to zbijamy do szeregowego, aby włączyć if( mvControlling->ScndCtrlPos > 0 ) { // jeżeli jest bocznik
// wysoki rozruch mvControlling->DecScndCtrl( 2 ); // wyłączyć bocznik, bo może blokować skręcenie NJ
if (mvControlling->ScndCtrlPos > 0) // jeżeli jest bocznik }
mvControlling->DecScndCtrl(2); // wyłączyć bocznik, bo może blokować skręcenie NJ do { // skręcanie do bezoporowej na szeregowym
do // skręcanie do bezoporowej na szeregowym mvControlling->DecMainCtrl( 1 ); // kręcimy nastawnik jazdy o 1 wstecz
mvControlling->DecMainCtrl(1); // kręcimy nastawnik jazdy o 1 wstecz }
while (mvControlling->MainCtrlPos ? while( ( false == mvControlling->IsMainCtrlNoPowerPos() )
mvControlling->RList[mvControlling->MainCtrlPos].Bn > 1 : && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 ) ); // oporowa zapętla
false); // oporowa zapętla
} }
if (mvControlling->Imax < mvControlling->ImaxHi) // jeśli da się na wysokim if( mvControlling->Imax < mvControlling->ImaxHi ) { // jeśli da się na wysokim
mvControlling->CurrentSwitch(true); // rozruch wysoki (za to może się ślizgać) mvControlling->CurrentSwitch( true ); // rozruch wysoki (za to może się ślizgać)
if (ReactionTime > 0.1) }
if( ReactionTime > 0.1 ) {
ReactionTime = 0.1; // orientuj się szybciej ReactionTime = 0.1; // orientuj się szybciej
}
} // if (Im>Imin) } // if (Im>Imin)
// NOTE: this step is likely to conflict with directive to operate sandbox based on the state of slipping wheels
// TODO: gather all sandbox operating logic in one place
if( fabs( mvControlling->Im ) > 0.75 * mvControlling->ImaxHi ) {
// jeśli prąd jest duży
mvControlling->Sandbox( true ); // piaskujemy tory, coby się nie ślizgać
} }
else { if( std::fabs( mvControlling->Im ) > 0.96 * mvControlling->Imax ) {// jeśli prąd jest duży (można 690 na 750)
// otherwise we switch the sander off, if it's active if( mvControlling->ScndCtrlPos > 0 ) { // jeżeli jest bocznik
if( mvControlling->SandDose ) { mvControlling->DecScndCtrl( 2 ); // zmniejszyć bocznik
mvControlling->Sandbox( false ); }
else {
mvControlling->DecMainCtrl( 1 ); // kręcimy nastawnik jazdy o 1 wstecz
} }
} }
if ((fabs(mvControlling->Im) > 0.96 * mvControlling->Imax) ||
mvControlling->SlippingWheels) // jeśli prąd jest duży (można 690 na 750)
if (mvControlling->ScndCtrlPos > 0) // jeżeli jest bocznik
mvControlling->DecScndCtrl(2); // zmniejszyć bocznik
else
mvControlling->DecMainCtrl(1); // kręcimy nastawnik jazdy o 1 wstecz
} }
else // gdy nie jedzie ambitnie pod górę // else // gdy nie jedzie ambitnie pod górę
{ // sprawdzenie, czy rozruch wysoki jest potrzebny { // sprawdzenie, czy rozruch wysoki jest potrzebny
if (mvControlling->Imax > mvControlling->ImaxLo) if( ( mvControlling->Imax > mvControlling->ImaxLo )
if (mvOccupied->Vel >= 30.0) // jak się rozpędził && ( mvOccupied->Vel >= 30.0 ) ) { // jak się rozpędził
if (fAccGravity > -0.02) // a i pochylenie mnijsze niż 2‰ // if (fAccGravity > -0.02) // a i pochylenie mnijsze niż 2‰
mvControlling->CurrentSwitch(false); // rozruch wysoki wyłącz mvControlling->CurrentSwitch( false ); // rozruch wysoki wyłącz
}
} }
} }
*/
break; break;
} }
case TEngineType::Dumb: { case TEngineType::Dumb: {
@@ -3926,13 +4034,14 @@ void TController::SetTimeControllers()
if( false == AIControllFlag ) { return; } if( false == AIControllFlag ) { return; }
//1. Check the type of Main Brake Handle //1. Check the type of Main Brake Handle
if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic) if( BrakeSystem == TBrakeSystem::Pneumatic || ForcePNBrake )
{ {
if (mvOccupied->Handle->Time) if (mvOccupied->Handle->Time)
{ {
if ((BrakeCtrlPosition > 0) && (mvOccupied->Handle->GetCP() - 0.05 > mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) auto const pressuredifference { mvOccupied->Handle->GetCP() - ( mvOccupied->HighPipePress - BrakeCtrlPosition * 0.25*mvOccupied->DeltaPipePress ) };
if ((BrakeCtrlPosition > 0) && (pressuredifference > 0.05))
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_FB)); mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_FB));
else if ((BrakeCtrlPosition > 0) && (mvOccupied->Handle->GetCP() + 0.05 < mvOccupied->HighPipePress - BrakeCtrlPosition*0.25*mvOccupied->DeltaPipePress)) else if ((BrakeCtrlPosition > 0) && (pressuredifference < -0.05))
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP));
else if (BrakeCtrlPosition == 0) else if (BrakeCtrlPosition == 0)
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP));
@@ -3941,21 +4050,29 @@ void TController::SetTimeControllers()
else if (BrakeCtrlPosition == -2) else if (BrakeCtrlPosition == -2)
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_NP)); mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_NP));
} }
if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) mvOccupied->BrakeLevelSet(BrakeCtrlPosition); if( mvOccupied->BrakeHandle == TBrakeHandle::FV4a ) {
if (mvOccupied->BrakeHandle == TBrakeHandle::MHZ_K8P) mvOccupied->BrakeLevelSet( BrakeCtrlPosition );
{ }
if (BrakeCtrlPosition == 0) if( ( mvOccupied->BrakeHandle == TBrakeHandle::MHZ_K8P )
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); || ( mvOccupied->BrakeHandle == TBrakeHandle::MHZ_EN57 ) ) {
else if (BrakeCtrlPosition == -1) if( BrakeCtrlPosition == 0 ) {
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_FS)); mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) );
else if (BrakeCtrlPosition == -2) }
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_NP)); else if( BrakeCtrlPosition == -1 ) {
else if (BrakeCtrlPosition > 4.5) mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) );
mvOccupied->BrakeLevelSet(10); }
else if (BrakeCtrlPosition > 3.70) else if( BrakeCtrlPosition == -2 ) {
mvOccupied->BrakeLevelSet(9); mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_NP ) );
else }
mvOccupied->BrakeLevelSet(round((BrakeCtrlPosition * 0.4 - 0.1) / 0.15)); else if( BrakeCtrlPosition > 4.5 ) {
mvOccupied->BrakeLevelSet( 10 );
}
else if( BrakeCtrlPosition > 3.70 ) {
mvOccupied->BrakeLevelSet( 9 );
}
else {
mvOccupied->BrakeLevelSet( round( ( BrakeCtrlPosition * 0.4 - 0.1 ) / 0.15 ) );
}
} }
} }
//2. Check the type of Secondary Brake Handle //2. Check the type of Secondary Brake Handle
@@ -4130,12 +4247,12 @@ void TController::CheckTimeControllers()
if( false == AIControllFlag ) { return; } if( false == AIControllFlag ) { return; }
//1. Check the type of Main Brake Handle //1. Check the type of Main Brake Handle
if (mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic && mvOccupied->Handle->TimeEP) if( BrakeSystem == TBrakeSystem::ElectroPneumatic && mvOccupied->Handle->TimeEP && !ForcePNBrake )
{ {
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EPN)); mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EPN));
} }
if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic && mvOccupied->Handle->Time) if( ( BrakeSystem == TBrakeSystem::Pneumatic || ForcePNBrake ) && mvOccupied->Handle->Time )
{ {
if (BrakeCtrlPosition > 0) if (BrakeCtrlPosition > 0)
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_MB)); mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_MB));
else else
@@ -5754,6 +5871,7 @@ void TController::ControllingSet()
lookup->MoverParameters : lookup->MoverParameters :
mvControlling ); mvControlling );
} }
BrakeSystem = consist_brake_system();
}; };
std::string TController::TableText( std::size_t const Index ) const std::string TController::TableText( std::size_t const Index ) const
@@ -5872,7 +5990,7 @@ TController::determine_consist_state() {
Ready = true; // wstępnie gotowy Ready = true; // wstępnie gotowy
fReady = 0.0; // założenie, że odhamowany fReady = 0.0; // założenie, że odhamowany
IsConsistBraked = ( IsConsistBraked = (
mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ? ( ( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) && ( false == ForcePNBrake ) ) ?
mvOccupied->BrakePress > 2.0 : mvOccupied->BrakePress > 2.0 :
mvOccupied->PipePress < std::max( 3.9, mvOccupied->BrakePressureActual.PipePressureVal ) + 0.1 ); mvOccupied->PipePress < std::max( 3.9, mvOccupied->BrakePressureActual.PipePressureVal ) + 0.1 );
fAccGravity = 0.0; // przyspieszenie wynikające z pochylenia fAccGravity = 0.0; // przyspieszenie wynikające z pochylenia
@@ -5888,8 +6006,10 @@ TController::determine_consist_state() {
auto const bp { std::max( 0.0, vehicle->BrakePress - ( vehicle->SpeedCtrlUnit.Parking ? vehicle->MaxBrakePress[ 0 ] * vehicle->StopBrakeDecc : 0.0 ) ) }; auto const bp { std::max( 0.0, vehicle->BrakePress - ( vehicle->SpeedCtrlUnit.Parking ? vehicle->MaxBrakePress[ 0 ] * vehicle->StopBrakeDecc : 0.0 ) ) };
if (Ready) { if (Ready) {
// bo jak coś nie odhamowane, to dalej nie ma co sprawdzać // bo jak coś nie odhamowane, to dalej nie ma co sprawdzać
if( ( TestFlag( vehicle->Hamulec->GetBrakeStatus(), b_hld ) ) if( ( TestFlagAny( vehicle->Hamulec->GetBrakeStatus(), ( b_hld | b_on ) ) )
|| ( ( vehicle->Vel < 1.0 ) && ( bp > 0.4 ) ) ) { // ensure the brakes are sufficiently released when starting to move || ( ( vehicle->Vel < 1.0 ?
( bp > 0.4 ) : // ensure the brakes are sufficiently released when starting to move
( vehicle->Fb * 0.001 > 10.0 ) ) ) ) { // once in motion we can make a more lenient check
Ready = false; Ready = false;
} }
// Ra: odluźnianie przeładowanych lokomotyw, ciągniętych na zimno - prowizorka... // Ra: odluźnianie przeładowanych lokomotyw, ciągniętych na zimno - prowizorka...
@@ -6028,6 +6148,9 @@ TController::control_wheelslip() {
cue_action( locale::string::driver_hint_antislip ); cue_action( locale::string::driver_hint_antislip );
++iDriverFailCount; ++iDriverFailCount;
} }
else if( std::fabs( mvControlling->Im ) > 0.75 * mvControlling->ImaxHi ) {
cue_action( locale::string::driver_hint_sandingon ); // piaskujemy tory, coby się nie ślizgać
}
else { else {
// deactivate sandbox if we aren't slipping // deactivate sandbox if we aren't slipping
if( mvControlling->SandDose ) { if( mvControlling->SandDose ) {
@@ -6970,7 +7093,7 @@ TController::UpdateDisconnect() {
else { else {
WriteLog( "Uncoupling [" + mvOccupied->Name + "]: direction change" ); WriteLog( "Uncoupling [" + mvOccupied->Name + "]: direction change" );
/* // TODO: test if this block is needed /* // TODO: test if this block is needed
if( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) { if( BrakeSystem == TBrakeSystem::ElectroPneumatic ) {
// wyłączenie EP, gdy wystarczy (może nie być potrzebne, bo na początku jest) // wyłączenie EP, gdy wystarczy (może nie być potrzebne, bo na początku jest)
mvOccupied->BrakeLevelSet( 0 ); mvOccupied->BrakeLevelSet( 0 );
} }
@@ -7159,6 +7282,7 @@ TController::pick_optimal_speed( double const Range ) {
adjust_desired_speed_for_limits(); adjust_desired_speed_for_limits();
adjust_desired_speed_for_target_speed( Range ); adjust_desired_speed_for_target_speed( Range );
adjust_desired_speed_for_current_speed(); adjust_desired_speed_for_current_speed();
adjust_desired_speed_for_braking_test();
// Ra 2F1I: wyłączyć kiedyś to uśrednianie i przeanalizować skanowanie, czemu migocze // Ra 2F1I: wyłączyć kiedyś to uśrednianie i przeanalizować skanowanie, czemu migocze
if( AccDesired > EU07_AI_NOACCELERATION ) { // hamowania lepeiej nie uśredniać if( AccDesired > EU07_AI_NOACCELERATION ) { // hamowania lepeiej nie uśredniać
@@ -7619,6 +7743,82 @@ TController::adjust_desired_speed_for_current_speed() {
} }
} }
// hamowanie kontrolne
void
TController::adjust_desired_speed_for_braking_test() {
// if( false == Global.DynamicBrakeTest ) { return; }
if( DynamicBrakeTest >= 5 ) { return; } // all done
if( false == is_train() ) { return; } // not applicable
if( false == TestFlag( OrderCurrentGet(), Obey_train ) ) { return; } // not applicable
if( false == AIControllFlag ) { return; } // TBD: add notification about braking test and enable it for human driver as well?
auto const vel { DirectionalVel() };
switch( DynamicBrakeTest ) {
case 0: {
if( ( primary() )
&& ( vel < VelDesired )
&& ( fAccGravity >= 0.0 ) // not if going uphill
&& ( AccDesired >= EU07_AI_ACCELERATION )
&& ( TrainParams.TTVmax >= 10.0 )
&& ( vel > std::min( TrainParams.TTVmax, 60.0 ) - 2.0 ) ) {
DynamicBrakeTest = 1;
DBT_BrakingTime = ElapsedTime;
DBT_VelocityBrake = vel;
}
break;
}
case 1: {
AccDesired = EU07_AI_BRAKINGTESTACCELERATION;
VelDesired = DBT_VelocityBrake;
if( ElapsedTime - DBT_BrakingTime > 1 ) {
ForcePNBrake = true;
mvOccupied->EpFuseSwitch( false );
DynamicBrakeTest = 2;
}
break;
}
case 2: {
AccDesired = EU07_AI_BRAKINGTESTACCELERATION;
VelDesired = DBT_VelocityBrake;
if( ElapsedTime - DBT_BrakingTime > 2 ) {
DBT_BrakingTime = ElapsedTime;
DBT_VelocityBrake = vel;
DBT_VelocityRelease = vel - 8.0;
DynamicBrakeTest = 3;
}
break;
}
case 3: {
AccDesired = clamp( -AbsAccS, fAccThreshold * 1.01, fAccThreshold * 1.21 );
VelDesired = DBT_VelocityBrake;
if( vel <= DBT_VelocityRelease ) {
DynamicBrakeTest = 4;
DBT_BrakingTime = ElapsedTime - DBT_BrakingTime;
DBT_MidPointAcc = AbsAccS;
DBT_ReleasingTime = ElapsedTime;
}
break;
}
case 4: {
if( Ready ) {
if( BrakeSystem == TBrakeSystem::ElectroPneumatic ) {
mvOccupied->EpFuseSwitch( true );
}
ForcePNBrake = false;
DynamicBrakeTest = 5;
DBT_ReleasingTime = ElapsedTime - DBT_ReleasingTime;
DBT_VelocityFinish = vel;
}
break;
}
default: {
break;
}
}
}
void void
TController::control_tractive_and_braking_force() { TController::control_tractive_and_braking_force() {
@@ -7701,7 +7901,7 @@ void TController::control_tractive_force() {
auto const velocity { DirectionalVel() }; auto const velocity { DirectionalVel() };
// jeśli przyspieszenie pojazdu jest mniejsze niż żądane oraz... // jeśli przyspieszenie pojazdu jest mniejsze niż żądane oraz...
if( ( AccDesired > EU07_AI_NOACCELERATION ) // don't add power if not asked for actual speed-up if( ( AccDesired > EU07_AI_NOACCELERATION ) // don't add power if not asked for actual speed-up
&& (( AbsAccS < AccDesired /* - 0.05 */ ) || (mvOccupied->SpeedCtrlUnit.IsActive && velocity < mvOccupied->SpeedCtrlUnit.FullPowerVelocity)) && (( AbsAccS < AccDesired - std::min( 0.05, 0.01 * iDriverFailCount ) ) || (mvOccupied->SpeedCtrlUnit.IsActive && velocity < mvOccupied->SpeedCtrlUnit.FullPowerVelocity))
&& ( false == TestFlag( iDrivigFlags, movePress ) ) ) { && ( false == TestFlag( iDrivigFlags, movePress ) ) ) {
// ...jeśli prędkość w kierunku czoła jest mniejsza od dozwolonej o margines... // ...jeśli prędkość w kierunku czoła jest mniejsza od dozwolonej o margines...
if( velocity < ( if( velocity < (
@@ -7780,7 +7980,7 @@ void TController::control_braking_force() {
} }
} }
if( is_emu() ) { if( is_emu() && ( !ForcePNBrake ) ) {
// właściwie, to warunek powinien być na działający EP // właściwie, to warunek powinien być na działający EP
// Ra: to dobrze hamuje EP w EZT // Ra: to dobrze hamuje EP w EZT
auto const accthreshold { ( auto const accthreshold { (
@@ -7896,7 +8096,7 @@ void TController::control_releaser() {
if( ( mvOccupied->Vel < 1.0 ) && ( fActionTime < 0.0 ) ) { return; } if( ( mvOccupied->Vel < 1.0 ) && ( fActionTime < 0.0 ) ) { return; }
// TODO: combine all releaser handling in single decision tree instead of having bits all over the place // TODO: combine all releaser handling in single decision tree instead of having bits all over the place
// TODO: replace handle and system conditions with flag indicating releaser presence // TODO: replace handle and system conditions with flag indicating releaser presence
if( mvOccupied->BrakeSystem != TBrakeSystem::Pneumatic ) { return; } if( BrakeSystem != TBrakeSystem::Pneumatic ) { return; }
auto const hasreleaser { auto const hasreleaser {
( false == ( is_dmu() || is_emu() ) ) // TODO: a more refined test than rejecting these types wholesale ( false == ( is_dmu() || is_emu() ) ) // TODO: a more refined test than rejecting these types wholesale
@@ -7964,7 +8164,7 @@ void TController::control_main_pipe() {
} }
// napełnianie uderzeniowe // napełnianie uderzeniowe
if( mvOccupied->BrakeSystem != TBrakeSystem::Pneumatic ) { return; } if( BrakeSystem != TBrakeSystem::Pneumatic ) { return; }
if( ( mvOccupied->BrakeHandle == TBrakeHandle::FV4a ) if( ( mvOccupied->BrakeHandle == TBrakeHandle::FV4a )
|| ( mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P ) || ( mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P )

View File

@@ -17,7 +17,9 @@ http://mozilla.org/MPL/2.0/.
#include "mtable.h" #include "mtable.h"
#include "translation.h" #include "translation.h"
auto const EU07_AI_ACCELERATION = 0.05;
auto const EU07_AI_NOACCELERATION = -0.05; auto const EU07_AI_NOACCELERATION = -0.05;
auto const EU07_AI_BRAKINGTESTACCELERATION = -0.06;
auto const EU07_AI_NOMOVEMENT = 0.05; // standstill velocity threshold auto const EU07_AI_NOMOVEMENT = 0.05; // standstill velocity threshold
auto const EU07_AI_MOVEMENT = 1.0; // deliberate movement velocity threshold auto const EU07_AI_MOVEMENT = 1.0; // deliberate movement velocity threshold
auto const EU07_AI_SPEEDLIMITEXTENDSBEYONDSCANRANGE = 10000.0; auto const EU07_AI_SPEEDLIMITEXTENDSBEYONDSCANRANGE = 10000.0;
@@ -61,7 +63,7 @@ enum TMovementStatus
moveVisibility = 0x10000, // jazda na widoczność po przejechaniu S1 na SBL moveVisibility = 0x10000, // jazda na widoczność po przejechaniu S1 na SBL
moveDoorOpened = 0x20000, // drzwi zostały otwarte - doliczyć czas na zamknięcie moveDoorOpened = 0x20000, // drzwi zostały otwarte - doliczyć czas na zamknięcie
movePushPull = 0x40000, // zmiana czoła przez zmianę kabiny - nie odczepiać przy zmianie kierunku movePushPull = 0x40000, // zmiana czoła przez zmianę kabiny - nie odczepiać przy zmianie kierunku
moveSemaphorFound = 0x80000, // na drodze skanowania został znaleziony semafor moveSignalFound = 0x80000, // na drodze skanowania został znaleziony semafor
moveStopPointFound = 0x100000 // stop point detected ahead moveStopPointFound = 0x100000 // stop point detected ahead
/* /*
moveSemaphorWasElapsed = 0x100000, // minięty został semafor moveSemaphorWasElapsed = 0x100000, // minięty został semafor
@@ -250,6 +252,7 @@ public:
return ( ( mvControlling->EngineType == TEngineType::DieselElectric ) return ( ( mvControlling->EngineType == TEngineType::DieselElectric )
|| ( mvControlling->EngineType == TEngineType::DieselEngine ) ); || ( mvControlling->EngineType == TEngineType::DieselEngine ) );
} }
TBrakeSystem consist_brake_system() const;
private: private:
void Activation(); // umieszczenie obsady w odpowiednim członie void Activation(); // umieszczenie obsady w odpowiednim członie
void ControllingSet(); // znajduje człon do sterowania void ControllingSet(); // znajduje człon do sterowania
@@ -327,6 +330,7 @@ private:
void adjust_desired_speed_for_limits(); void adjust_desired_speed_for_limits();
void adjust_desired_speed_for_target_speed( double const Range ); void adjust_desired_speed_for_target_speed( double const Range );
void adjust_desired_speed_for_current_speed(); void adjust_desired_speed_for_current_speed();
void adjust_desired_speed_for_braking_test();
void control_tractive_and_braking_force(); void control_tractive_and_braking_force();
void control_releaser(); void control_releaser();
void control_main_pipe(); void control_main_pipe();
@@ -431,6 +435,16 @@ private:
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
double BrakeChargingCooldown{}; // prevents the ai from trying to charge the train brake too frequently double BrakeChargingCooldown{}; // prevents the ai from trying to charge the train brake too frequently
TBrakeSystem BrakeSystem = TBrakeSystem::Individual; //type of main brake
bool ForcePNBrake = false; //is it necessary to use PN brake instead of EP brake
int DynamicBrakeTest = 0; //is it necessary to make brake test while driving
double DBT_VelocityBrake = 0;
double DBT_VelocityRelease = 0;
double DBT_VelocityFinish = 0;
double DBT_BrakingTime = 0;
double DBT_ReleasingTime = 0;
double DBT_MidPointAcc = 0;
int StaticBrakeTest = 0; //is it necessary to make brake test while standing
double LastReactionTime = 0.0; double LastReactionTime = 0.0;
double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi
double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations

View File

@@ -2093,6 +2093,28 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
MoverParameters->dizel_HeatSet( Global.AirTemperature ); MoverParameters->dizel_HeatSet( Global.AirTemperature );
} }
} // temperature } // temperature
else if( ( ActPar.size() >= 2 )
&& ( ActPar.front() == 'L' ) ) {
// load
ActPar.erase( 0, 1 );
// immediately followed by max load override
// TBD: make it instead an optional sub-parameter?
{
auto const indexstart { 0 };
auto const indexend { ActPar.find_first_not_of( "1234567890", indexstart ) };
MoverParameters->MaxLoad = std::atoi( ActPar.substr( indexstart, indexend ).c_str() );
ActPar.erase( 0, indexend );
}
while( false == ActPar.empty() ) {
switch( ActPar.front() ) {
default: {
// unrecognized key
ActPar.erase( 0, 1 );
break;
}
}
}
} // load
/* else if (ActPar.substr(0, 1) == "") // tu mozna wpisac inny prefiks i inne rzeczy /* else if (ActPar.substr(0, 1) == "") // tu mozna wpisac inny prefiks i inne rzeczy
{ {
// jakies inne prefiksy // jakies inne prefiksy

View File

@@ -1193,6 +1193,7 @@ public:
int IminLo = 0; int IminHi = 0; /*prady przelacznika automatycznego rozruchu, uzywane tez przez ai_driver*/ int IminLo = 0; int IminHi = 0; /*prady przelacznika automatycznego rozruchu, uzywane tez przez ai_driver*/
int ImaxLo = 0; // maksymalny prad niskiego rozruchu int ImaxLo = 0; // maksymalny prad niskiego rozruchu
int ImaxHi = 0; // maksymalny prad wysokiego rozruchu int ImaxHi = 0; // maksymalny prad wysokiego rozruchu
bool MotorOverloadRelayHighThreshold { false };
double nmax = 0.0; /*maksymalna dop. ilosc obrotow /s*/ double nmax = 0.0; /*maksymalna dop. ilosc obrotow /s*/
double InitialCtrlDelay = 0.0; double CtrlDelay = 0.0; /* -//- -//- miedzy kolejnymi poz.*/ double InitialCtrlDelay = 0.0; double CtrlDelay = 0.0; /* -//- -//- miedzy kolejnymi poz.*/
double CtrlDownDelay = 0.0; /* -//- -//- przy schodzeniu z poz.*/ /*hunter-101012*/ double CtrlDownDelay = 0.0; /* -//- -//- przy schodzeniu z poz.*/ /*hunter-101012*/
@@ -1675,6 +1676,7 @@ public:
bool DecBrakeLevel(); bool DecBrakeLevel();
bool ChangeCab(int direction); bool ChangeCab(int direction);
bool CurrentSwitch(bool const State); bool CurrentSwitch(bool const State);
bool IsMotorOverloadRelayHighThresholdOn() const;
void UpdateBatteryVoltage(double dt); void UpdateBatteryVoltage(double dt);
double ComputeMovement(double dt, double dt1, const TTrackShape &Shape, TTrackParam &Track, TTractionParam &ElectricTraction, TLocation const &NewLoc, TRotation const &NewRot); //oblicza przesuniecie pojazdu double ComputeMovement(double dt, double dt1, const TTrackShape &Shape, TTrackParam &Track, TTractionParam &ElectricTraction, TLocation const &NewLoc, TRotation const &NewRot); //oblicza przesuniecie pojazdu
double FastComputeMovement(double dt, const TTrackShape &Shape, TTrackParam &Track, TLocation const &NewLoc, TRotation const &NewRot); //oblicza przesuniecie pojazdu - wersja zoptymalizowana double FastComputeMovement(double dt, const TTrackShape &Shape, TTrackParam &Track, TLocation const &NewLoc, TRotation const &NewRot); //oblicza przesuniecie pojazdu - wersja zoptymalizowana
@@ -1841,7 +1843,7 @@ public:
bool CutOffEngine(void); //odlaczenie udszkodzonych silnikow bool CutOffEngine(void); //odlaczenie udszkodzonych silnikow
/*funkcje automatycznego rozruchu np EN57*/ /*funkcje automatycznego rozruchu np EN57*/
bool MaxCurrentSwitch(bool State); //przelacznik pradu wysokiego rozruchu bool MaxCurrentSwitch(bool State, range_t const Notify = range_t::consist ); //przelacznik pradu wysokiego rozruchu
bool MinCurrentSwitch(bool State); //przelacznik pradu automatycznego rozruchu bool MinCurrentSwitch(bool State); //przelacznik pradu automatycznego rozruchu
bool AutoRelaySwitch(bool State); //przelacznik automatycznego rozruchu bool AutoRelaySwitch(bool State); //przelacznik automatycznego rozruchu
bool AutoRelayCheck();//symulacja automatycznego rozruchu bool AutoRelayCheck();//symulacja automatycznego rozruchu

View File

@@ -674,6 +674,12 @@ TMoverParameters::CurrentSwitch(bool const State) {
return false; return false;
}; };
bool
TMoverParameters::IsMotorOverloadRelayHighThresholdOn() const {
return ( ( ImaxHi > ImaxLo ) && ( Imax > ImaxLo ) );
}
// KURS90 - sprężarka pantografów; Ra 2014-07: teraz jest to zbiornik rozrządu, chociaż to jeszcze nie tak // KURS90 - sprężarka pantografów; Ra 2014-07: teraz jest to zbiornik rozrządu, chociaż to jeszcze nie tak
void TMoverParameters::UpdatePantVolume(double dt) { void TMoverParameters::UpdatePantVolume(double dt) {
// check the pantograph compressor while at it // check the pantograph compressor while at it
@@ -1419,6 +1425,23 @@ void TMoverParameters::compute_movement_( double const Deltatime ) {
RunInternalCommand(); RunInternalCommand();
// relay settings
if( EngineType == TEngineType::ElectricSeriesMotor ) {
// adjust motor overload relay threshold
if( ImaxHi > ImaxLo ) {
if( MotorOverloadRelayHighThreshold ) { // set high threshold
if( ( TrainType != dt_ET42 ) ? ( RList[ MainCtrlPos ].Bn < 2 ) : ( MainCtrlPos == 0 ) ) {
Imax = ImaxHi;
}
}
else { // set low threshold
if( ( TrainType != dt_ET42 ) || ( MainCtrlPos == 0 ) ) {
Imax = ImaxLo;
}
}
}
}
// automatyczny rozruch // automatyczny rozruch
if( EngineType == TEngineType::ElectricSeriesMotor ) { if( EngineType == TEngineType::ElectricSeriesMotor ) {
if( AutoRelayCheck() ) { if( AutoRelayCheck() ) {
@@ -2233,14 +2256,12 @@ bool TMoverParameters::IncMainCtrl(int CtrlSpeed)
OK = true; OK = true;
if( Imax == ImaxHi ) { if( Imax == ImaxHi ) {
if( RList[ MainCtrlPos ].Bn > 1 ) { if( RList[ MainCtrlPos ].Bn > 1 ) {
/* NOTE: disabled, relay configuration was moved to compute_movement_
if( true == MaxCurrentSwitch( false )) { if( true == MaxCurrentSwitch( false )) {
// wylaczanie wysokiego rozruchu // wylaczanie wysokiego rozruchu
SetFlag( SoundFlag, sound::relay ); SetFlag( SoundFlag, sound::relay );
} // Q TODO: }
// if (EngineType=ElectricSeriesMotor) and (MainCtrlPos=1) */
// then
// MainCtrlActualPos:=1;
//
if( TrainType == dt_ET42 ) { if( TrainType == dt_ET42 ) {
--MainCtrlPos; --MainCtrlPos;
OK = false; OK = false;
@@ -3957,7 +3978,7 @@ bool TMoverParameters::SwitchEPBrake(int state)
if ((BrakeHandle == TBrakeHandle::St113) && (CabOccupied != 0)) if ((BrakeHandle == TBrakeHandle::St113) && (CabOccupied != 0))
{ {
if (state > 0) if (state > 0)
temp = Handle->GetCP(); // TODO: przetlumaczyc temp = Handle->GetEP(); // TODO: przetlumaczyc
else else
temp = 0; temp = 0;
Hamulec->SetEPS(temp); Hamulec->SetEPS(temp);
@@ -4519,7 +4540,7 @@ void TMoverParameters::UpdatePipePressure(double dt)
&& (DirActive != 0) && (DirActive != 0)
&& (EpFuse)) // tu powinien byc jeszcze bezpiecznik EP i baterie - && (EpFuse)) // tu powinien byc jeszcze bezpiecznik EP i baterie -
// temp = (Handle as TFVel6).GetCP // temp = (Handle as TFVel6).GetCP
temp = Handle->GetCP(); temp = Handle->GetEP();
else else
temp = 0.0; temp = 0.0;
@@ -6571,33 +6592,23 @@ bool TMoverParameters::CutOffEngine(void)
// Q: 20160713 // Q: 20160713
// Przełączenie wysoki / niski prąd rozruchu // Przełączenie wysoki / niski prąd rozruchu
// ************************************************************************************************* // *************************************************************************************************
bool TMoverParameters::MaxCurrentSwitch(bool State) bool TMoverParameters::MaxCurrentSwitch(bool State, range_t const Notify )
{ {
bool MCS = false; auto const initialstate { MotorOverloadRelayHighThreshold };
if (EngineType == TEngineType::ElectricSeriesMotor)
if (ImaxHi > ImaxLo)
{
if (State && (Imax == ImaxLo) && (RList[MainCtrlPos].Bn < 2) &&
!((TrainType == dt_ET42) && (MainCtrlPos > 0)))
{
Imax = ImaxHi; MotorOverloadRelayHighThreshold = State;
MCS = true;
if (CabActive != 0)
SendCtrlToNext("MaxCurrentSwitch", 1, CabActive);
}
if (!State)
if (Imax == ImaxHi) if( Notify != range_t::local ) {
if (!((TrainType == dt_ET42) && (MainCtrlPos > 0))) SendCtrlToNext(
{ "MaxCurrentSwitch",
Imax = ImaxLo; ( State ? 1 : 0 ),
MCS = true; CabActive,
if (CabActive != 0) ( Notify == range_t::unit ?
SendCtrlToNext("MaxCurrentSwitch", 0, CabActive); coupling::control | coupling::permanent :
} coupling::control ) );
} }
return MCS;
return State != initialstate;
} }
// ************************************************************************************************* // *************************************************************************************************
@@ -6739,19 +6750,24 @@ bool TMoverParameters::AutoRelayCheck(void)
} }
else else
{ // zmieniaj mainctrlactualpos { // zmieniaj mainctrlactualpos
if ((DirActive < 0) && (TrainType != dt_PseudoDiesel)) if( ( DirActive < 0 ) && ( TrainType != dt_PseudoDiesel ) ) {
if (RList[MainCtrlActualPos + 1].Bn > 1) if( RList[ MainCtrlActualPos + 1 ].Bn > 1 ) {
{
return false; // nie poprawiamy przy konwersji return false; // nie poprawiamy przy konwersji
// return ARC;// bbylo exit; //Ra: to powoduje, że EN57 nie wyłącza się przy // return ARC;// bbylo exit; //Ra: to powoduje, że EN57 nie wyłącza się przy IminLo
// IminLo
} }
}
// main bez samoczynnego rozruchu // main bez samoczynnego rozruchu
if( ( MainCtrlActualPos < ( sizeof( RList ) / sizeof( TScheme ) - 1 ) ) // crude guard against running out of current fixed table if( ( MainCtrlActualPos < ( sizeof( RList ) / sizeof( TScheme ) - 1 ) ) // crude guard against running out of current fixed table
&& ( ( RList[ MainCtrlActualPos ].Relay < MainCtrlPos ) && ( ( RList[ MainCtrlActualPos ].Relay < MainCtrlPos )
|| ( ( RList[ MainCtrlActualPos + 1 ].Relay == MainCtrlPos ) && ( MainCtrlActualPos < RlistSize ) ) || ( ( RList[ MainCtrlActualPos + 1 ].Relay == MainCtrlPos ) && ( MainCtrlActualPos < RlistSize ) )
|| ( ( TrainType == dt_ET22 ) && ( DelayCtrlFlag ) ) ) ) { || ( ( TrainType == dt_ET22 ) && ( DelayCtrlFlag ) ) ) ) {
// prevent switch to parallel mode if motor overload relay is set to high threshold mode
if( ( IsMotorOverloadRelayHighThresholdOn() )
&& ( RList[ MainCtrlActualPos + 1 ].Bn > 1 ) ) {
return false;
}
if( ( RList[MainCtrlPos].R == 0 ) if( ( RList[MainCtrlPos].R == 0 )
&& ( MainCtrlPos > 0 ) && ( MainCtrlPos > 0 )
&& ( MainCtrlPos != MainCtrlPosNo ) && ( MainCtrlPos != MainCtrlPosNo )
@@ -11994,10 +12010,10 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
DropAllPantographs( CValue1 == 1, range_t::local ); DropAllPantographs( CValue1 == 1, range_t::local );
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype ); OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
} }
else if (Command == "MaxCurrentSwitch") else if (Command == "MaxCurrentSwitch") {
{ MaxCurrentSwitch( CValue1 == 1, range_t::local );
OK = MaxCurrentSwitch(CValue1 == 1); OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
} }
else if (Command == "MinCurrentSwitch") else if (Command == "MinCurrentSwitch")
{ {
OK = MinCurrentSwitch(CValue1 == 1); OK = MinCurrentSwitch(CValue1 == 1);

View File

@@ -2282,6 +2282,11 @@ double TDriverHandle::GetCP()
return 0; return 0;
} }
double TDriverHandle::GetEP()
{
return 0;
}
double TDriverHandle::GetSound(int i) double TDriverHandle::GetSound(int i)
{ {
return 0; return 0;
@@ -2814,8 +2819,8 @@ double TMHZ_K5P::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
void TMHZ_K5P::Init(double Press) void TMHZ_K5P::Init(double Press)
{ {
CP = Press; CP = Press;
Time = true; Time = true;
TimeEP = true; TimeEP = true;
} }
void TMHZ_K5P::SetReductor(double nAdj) void TMHZ_K5P::SetReductor(double nAdj)
@@ -3133,9 +3138,11 @@ double TSt113::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
double ActFlowSpeed; double ActFlowSpeed;
int BCP; int BCP;
CP = PP;
BCP = lround(i_bcp); BCP = lround(i_bcp);
EPS = BEP_K[BCP+1]; EPS = BEP_K[BCP];
if (BCP > 0) if (BCP > 0)
BCP = BCP - 1; BCP = BCP - 1;
@@ -3169,7 +3176,12 @@ double TSt113::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
double TSt113::GetCP() double TSt113::GetCP()
{ {
return EPS; return CP;
}
double TSt113::GetEP()
{
return EPS;
} }
double TSt113::GetPos(int i) double TSt113::GetPos(int i)
@@ -3301,6 +3313,8 @@ double TFVel6::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
double dpMainValve; double dpMainValve;
double ActFlowSpeed; double ActFlowSpeed;
CP = PP;
LimPP = Min0R(5 * int(i_bcp < 3.5), HP); LimPP = Min0R(5 * int(i_bcp < 3.5), HP);
if ((i_bcp >= 3.5) && ((i_bcp < 4.3) || (i_bcp > 5.5))) if ((i_bcp >= 3.5) && ((i_bcp < 4.3) || (i_bcp > 5.5)))
ActFlowSpeed = 0; ActFlowSpeed = 0;
@@ -3334,7 +3348,12 @@ double TFVel6::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
double TFVel6::GetCP() double TFVel6::GetCP()
{ {
return EPS; return CP;
}
double TFVel6::GetEP()
{
return EPS;
} }
double TFVel6::GetPos(int i) double TFVel6::GetPos(int i)
@@ -3366,6 +3385,8 @@ double TFVE408::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
double dpMainValve; double dpMainValve;
double ActFlowSpeed; double ActFlowSpeed;
CP = PP;
LimPP = Min0R(5 * int(i_bcp < 6.5), HP); LimPP = Min0R(5 * int(i_bcp < 6.5), HP);
if ((i_bcp >= 6.5) && ((i_bcp < 7.5) || (i_bcp > 9.5))) if ((i_bcp >= 6.5) && ((i_bcp < 7.5) || (i_bcp > 9.5)))
ActFlowSpeed = 0; ActFlowSpeed = 0;
@@ -3398,6 +3419,11 @@ double TFVE408::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
} }
double TFVE408::GetCP() double TFVE408::GetCP()
{
return CP;
}
double TFVE408::GetEP()
{ {
return EPS; return EPS;
} }

View File

@@ -541,6 +541,7 @@ class TDriverHandle {
virtual double GetPF(double i_bcp, double PP, double HP, double dt, double ep); virtual double GetPF(double i_bcp, double PP, double HP, double dt, double ep);
virtual void Init(double Press); virtual void Init(double Press);
virtual double GetCP(); virtual double GetCP();
virtual double GetEP();
virtual void SetReductor(double nAdj); //korekcja pozycji reduktora cisnienia virtual void SetReductor(double nAdj); //korekcja pozycji reduktora cisnienia
virtual double GetSound(int i); //pobranie glosnosci wybranego dzwieku virtual double GetSound(int i); //pobranie glosnosci wybranego dzwieku
virtual double GetPos(int i); //pobranie numeru pozycji o zadanym kodzie (funkcji) virtual double GetPos(int i); //pobranie numeru pozycji o zadanym kodzie (funkcji)
@@ -617,7 +618,7 @@ class TMHZ_EN57 : public TDriverHandle {
double GetSound(int i)/*override*/; double GetSound(int i)/*override*/;
double GetPos(int i)/*override*/; double GetPos(int i)/*override*/;
double GetCP()/*override*/; double GetCP()/*override*/;
double GetEP(double pos); double GetEP(double pos);
void SetParams(bool AO, bool MO, double OverP, double, double OMP, double OPD); void SetParams(bool AO, bool MO, double OverP, double, double OMP, double OPD);
inline TMHZ_EN57(void) : inline TMHZ_EN57(void) :
TDriverHandle() TDriverHandle()
@@ -762,10 +763,11 @@ class TSt113 : public TH14K1 {
static double const BPT_K[/*?*/ /*-1..4*/ (4) - (-1) + 1][2]; static double const BPT_K[/*?*/ /*-1..4*/ (4) - (-1) + 1][2];
static double const BEP_K[/*?*/ /*-1..5*/ (5) - (-1) + 1]; static double const BEP_K[/*?*/ /*-1..5*/ (5) - (-1) + 1];
static double const pos_table[11]; // = {-1, 5, -1, 0, 2, 3, 4, 5, 0, 0, 1}; static double const pos_table[11]; // = {-1, 5, -1, 0, 2, 3, 4, 5, 0, 0, 1};
double CP = 0;
public: public:
double GetPF(double i_bcp, double PP, double HP, double dt, double ep)/*override*/; double GetPF(double i_bcp, double PP, double HP, double dt, double ep)/*override*/;
double GetCP()/*override*/; double GetCP()/*override*/;
double GetEP()/*override*/;
double GetPos(int i)/*override*/; double GetPos(int i)/*override*/;
void Init(double Press)/*override*/; void Init(double Press)/*override*/;
@@ -830,10 +832,12 @@ class TFVel6 : public TDriverHandle {
private: private:
double EPS = 0.0; double EPS = 0.0;
static double const pos_table[ 11 ]; // = {-1, 6, -1, 0, 6, 4, 4.7, 5, -1, 0, 1}; static double const pos_table[ 11 ]; // = {-1, 6, -1, 0, 6, 4, 4.7, 5, -1, 0, 1};
double CP = 0.0;
public: public:
double GetPF(double i_bcp, double PP, double HP, double dt, double ep)/*override*/; double GetPF(double i_bcp, double PP, double HP, double dt, double ep)/*override*/;
double GetCP()/*override*/; double GetCP()/*override*/;
double GetEP()/*override*/;
double GetPos(int i)/*override*/; double GetPos(int i)/*override*/;
double GetSound(int i)/*override*/; double GetSound(int i)/*override*/;
void Init(double Press)/*override*/; void Init(double Press)/*override*/;
@@ -848,10 +852,12 @@ class TFVE408 : public TDriverHandle {
private: private:
double EPS = 0.0; double EPS = 0.0;
static double const pos_table[11]; // = {-1, 6, -1, 0, 6, 4, 4.7, 5, -1, 0, 1}; static double const pos_table[11]; // = {-1, 6, -1, 0, 6, 4, 4.7, 5, -1, 0, 1};
double CP = 0.0;
public: public:
double GetPF(double i_bcp, double PP, double HP, double dt, double ep)/*override*/; double GetPF(double i_bcp, double PP, double HP, double dt, double ep)/*override*/;
double GetCP()/*override*/; double GetCP()/*override*/;
double GetEP()/*override*/;
double GetPos(int i)/*override*/; double GetPos(int i)/*override*/;
double GetSound(int i)/*override*/; double GetSound(int i)/*override*/;
void Init(double Press)/*override*/; void Init(double Press)/*override*/;

View File

@@ -3823,7 +3823,7 @@ void TTrain::OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
if( ( true == Train->mvControlled->ShuntModeAllow ? if( ( true == Train->mvControlled->ShuntModeAllow ?
( false == Train->mvControlled->ShuntMode ) : ( false == Train->mvControlled->ShuntMode ) :
( Train->mvControlled->Imax < Train->mvControlled->ImaxHi ) ) ) { ( false == Train->mvControlled->MotorOverloadRelayHighThreshold ) ) ) {
// turn on // turn on
OnCommand_motoroverloadrelaythresholdsethigh( Train, Command ); OnCommand_motoroverloadrelaythresholdsethigh( Train, Command );
} }
@@ -3838,10 +3838,9 @@ void TTrain::OnCommand_motoroverloadrelaythresholdsetlow( TTrain *Train, command
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
if( true == Train->mvControlled->CurrentSwitch( false ) ) { Train->mvControlled->CurrentSwitch( false );
// visual feedback // visual feedback
Train->ggMaxCurrentCtrl.UpdateValue( 0.0, Train->dsbSwitch ); Train->ggMaxCurrentCtrl.UpdateValue( Train->mvControlled->MotorOverloadRelayHighThreshold ? 1 : 0, Train->dsbSwitch );
}
} }
} }
@@ -3849,10 +3848,9 @@ void TTrain::OnCommand_motoroverloadrelaythresholdsethigh( TTrain *Train, comman
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
if( true == Train->mvControlled->CurrentSwitch( true ) ) { Train->mvControlled->CurrentSwitch( true );
// visual feedback // visual feedback
Train->ggMaxCurrentCtrl.UpdateValue( 1.0, Train->dsbSwitch ); Train->ggMaxCurrentCtrl.UpdateValue( Train->mvControlled->MotorOverloadRelayHighThreshold ? 1 : 0, Train->dsbSwitch );
}
} }
} }
@@ -7223,6 +7221,14 @@ bool TTrain::Update( double const Deltatime )
ggBrakeProfileG.Update(); ggBrakeProfileG.Update();
ggBrakeProfileR.Update(); ggBrakeProfileR.Update();
ggBrakeOperationModeCtrl.Update(); ggBrakeOperationModeCtrl.Update();
ggMaxCurrentCtrl.UpdateValue(
( true == mvControlled->ShuntModeAllow ?
( true == mvControlled->ShuntMode ?
1.f :
0.f ) :
( mvControlled->MotorOverloadRelayHighThreshold ?
1.f :
0.f ) ) );
ggMaxCurrentCtrl.Update(); ggMaxCurrentCtrl.Update();
// NBMX wrzesien 2003 - drzwi // NBMX wrzesien 2003 - drzwi
ggDoorLeftPermitButton.Update( lowvoltagepower ); ggDoorLeftPermitButton.Update( lowvoltagepower );
@@ -8873,7 +8879,7 @@ void TTrain::set_cab_controls( int const Cab ) {
( true == mvControlled->ShuntMode ? ( true == mvControlled->ShuntMode ?
1.f : 1.f :
0.f ) : 0.f ) :
( mvControlled->Imax == mvControlled->ImaxHi ? ( mvControlled->MotorOverloadRelayHighThreshold ?
1.f : 1.f :
0.f ) ) ); 0.f ) ) );
// lights // lights

View File

@@ -783,7 +783,7 @@ TController::cue_action( locale::string const Action, float const Actionparamete
case locale::string::driver_hint_trainbrakeapply: { case locale::string::driver_hint_trainbrakeapply: {
if( AIControllFlag ) { if( AIControllFlag ) {
// za radą yB ustawiamy pozycję 3 kranu (ruszanie kranem w innych miejscach powino zostać wyłączone) // za radą yB ustawiamy pozycję 3 kranu (ruszanie kranem w innych miejscach powino zostać wyłączone)
if( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) { if( ( BrakeSystem == TBrakeSystem::ElectroPneumatic ) && ( false == ForcePNBrake ) ) {
mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_EPB ) ); mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_EPB ) );
} }
else { else {

View File

@@ -1171,7 +1171,11 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
"Brakes:\n highest pressure: " + to_string( mechanik.fReady, 2 ) + ( mechanik.Ready ? " (all brakes released)" : "" ) "Brakes:\n highest pressure: " + to_string( mechanik.fReady, 2 ) + ( mechanik.Ready ? " (all brakes released)" : "" )
+ "\n activation threshold: " + to_string( mechanik.fAccThreshold, 2 ) + "\n activation threshold: " + to_string( mechanik.fAccThreshold, 2 )
+ ", delays: " + to_string( mechanik.fBrake_a0[ 0 ], 2 ) + " + " + to_string( mechanik.fBrake_a1[ 0 ], 2 ) + ", delays: " + to_string( mechanik.fBrake_a0[ 0 ], 2 ) + " + " + to_string( mechanik.fBrake_a1[ 0 ], 2 )
+ "\n virtual brake position: " + to_string( mechanik.BrakeCtrlPosition, 2 ); + "\n virtual brake position: " + to_string( mechanik.BrakeCtrlPosition, 2 )
+ "\n test stage: " + to_string( mechanik.DynamicBrakeTest )
+ ", applied at: " + to_string( mechanik.DBT_VelocityBrake, 0 )
+ ", release at: " + to_string( mechanik.DBT_VelocityRelease, 0 )
+ ", done at: " + to_string( mechanik.DBT_VelocityFinish, 0 );
Output.emplace_back( textline, Global.UITextColor ); Output.emplace_back( textline, Global.UITextColor );
@@ -1179,7 +1183,7 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
std::vector<std::string> const drivingflagnames { std::vector<std::string> const drivingflagnames {
"StopCloser", "StopPoint", "Active", "Press", "Connect", "Primary", "Late", "StopHere", "StopCloser", "StopPoint", "Active", "Press", "Connect", "Primary", "Late", "StopHere",
"StartHorn", "StartHornNow", "StartHornDone", "Oerlikons", "IncSpeed", "TrackEnd", "SwitchFound", "GuardSignal", "StartHorn", "StartHornNow", "StartHornDone", "Oerlikons", "IncSpeed", "TrackEnd", "SwitchFound", "GuardSignal",
"Visibility", "DoorOpened", "PushPull", "SemaphorFound", "StopPointFound" /*"SemaphorWasElapsed", "TrainInsideStation", "SpeedLimitFound"*/ }; "Visibility", "DoorOpened", "PushPull", "SignalFound", "StopPointFound" /*"SemaphorWasElapsed", "TrainInsideStation", "SpeedLimitFound"*/ };
textline = "Driving flags:"; textline = "Driving flags:";
for( int idx = 0, flagbit = 1; idx < drivingflagnames.size(); ++idx, flagbit <<= 1 ) { for( int idx = 0, flagbit = 1; idx < drivingflagnames.size(); ++idx, flagbit <<= 1 ) {

View File

@@ -90,7 +90,14 @@ std::string Now();
double CompareTime( double t1h, double t1m, double t2h, double t2m ); double CompareTime( double t1h, double t1m, double t2h, double t2m );
/*funkcje logiczne*/ /*funkcje logiczne*/
inline bool TestFlag( int const Flag, int const Value ) { return ( ( Flag & Value ) == Value ); } inline
bool TestFlag( int const Flag, int const Value ) {
return ( ( Flag & Value ) == Value );
}
inline
bool TestFlagAny( int const Flag, int const Value ) {
return ( ( Flag & Value ) != 0 );
}
bool SetFlag( int &Flag, int const Value); bool SetFlag( int &Flag, int const Value);
bool ClearFlag(int &Flag, int const Value); bool ClearFlag(int &Flag, int const Value);
@@ -117,8 +124,8 @@ std::string to_string(double Value, int precision, int width);
std::string to_hex_str( int const Value, int const width = 4 ); std::string to_hex_str( int const Value, int const width = 4 );
std::string to_minutes_str( float const Minutes, bool const Leadingzero, int const Width ); std::string to_minutes_str( float const Minutes, bool const Leadingzero, int const Width );
inline std::string to_string(bool Value) { inline
std::string to_string(bool Value) {
return ( Value == true ? "true" : "false" ); return ( Value == true ? "true" : "false" );
} }