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

vehicle controllers ai logic fixes, minor refactoring

This commit is contained in:
tmj-fstate
2019-03-19 22:38:46 +01:00
parent 3edd22e9fa
commit fe6789778f
6 changed files with 154 additions and 103 deletions

View File

@@ -1765,15 +1765,10 @@ void TController::Activation()
if (iDirection) if (iDirection)
{ // jeśli jest ustalony kierunek { // jeśli jest ustalony kierunek
TDynamicObject *old = pVehicle, *d = pVehicle; // w tym siedzi AI TDynamicObject *old = pVehicle, *d = pVehicle; // w tym siedzi AI
TController *drugi; // jakby były dwa, to zamienić miejscami, a nie robić wycieku pamięci TController *drugi; // jakby były dwa, to zamienić miejscami, a nie robić wycieku pamięci poprzez nadpisanie
// poprzez nadpisanie
auto const localbrakelevel { mvOccupied->LocalBrakePosA }; auto const localbrakelevel { mvOccupied->LocalBrakePosA };
while (mvControlling->MainCtrlPos) // samo zapętlenie DecSpeed() nie wystarcza :/ ZeroSpeed();
DecSpeed(true); // wymuszenie zerowania nastawnika jazdy ZeroDirection();
while (mvOccupied->ActiveDir < 0)
mvOccupied->DirectionForward(); // kierunek na 0
while (mvOccupied->ActiveDir > 0)
mvOccupied->DirectionBackward();
if (TestFlag(d->MoverParameters->Couplers[iDirectionOrder < 0 ? 1 : 0].CouplingFlag, ctrain_controll)) { if (TestFlag(d->MoverParameters->Couplers[iDirectionOrder < 0 ? 1 : 0].CouplingFlag, ctrain_controll)) {
mvControlling->MainSwitch( false); // dezaktywacja czuwaka, jeśli przejście do innego członu mvControlling->MainSwitch( false); // dezaktywacja czuwaka, jeśli przejście do innego członu
mvOccupied->DecLocalBrakeLevel(LocalBrakePosNo); // zwolnienie hamulca w opuszczanym pojeździe mvOccupied->DecLocalBrakeLevel(LocalBrakePosNo); // zwolnienie hamulca w opuszczanym pojeździe
@@ -2396,7 +2391,7 @@ void TController::SetDriverPsyche()
} }
if (mvControlling && mvOccupied) if (mvControlling && mvOccupied)
{ // with Controlling do { // with Controlling do
if (mvControlling->MainCtrlPos < 3) if (mvControlling->MainCtrlPowerPos() < 3)
ReactionTime = mvControlling->InitialCtrlDelay + ReactionTime; ReactionTime = mvControlling->InitialCtrlDelay + ReactionTime;
if (mvOccupied->BrakeCtrlPos > 1) if (mvOccupied->BrakeCtrlPos > 1)
ReactionTime = 0.5 * ReactionTime; ReactionTime = 0.5 * ReactionTime;
@@ -2493,17 +2488,16 @@ bool TController::PrepareEngine()
{ // część wykonawcza dla sterowania przez komputer { // część wykonawcza dla sterowania przez komputer
if (mvControlling->ConvOvldFlag) if (mvControlling->ConvOvldFlag)
{ // wywalił bezpiecznik nadmiarowy przetwornicy { // wywalił bezpiecznik nadmiarowy przetwornicy
while (DecSpeed(true)) ZeroSpeed();
; // zerowanie napędu
mvControlling->ConvOvldFlag = false; // reset nadmiarowego mvControlling->ConvOvldFlag = false; // reset nadmiarowego
} }
else if (false == IsLineBreakerClosed) { else if (false == IsLineBreakerClosed) {
while (DecSpeed(true)) ZeroSpeed();
; // zerowanie napędu
if( mvOccupied->TrainType == dt_SN61 ) { if( mvOccupied->TrainType == dt_SN61 ) {
// specjalnie dla SN61 żeby nie zgasł // specjalnie dla SN61 żeby nie zgasł
if( mvControlling->RList[ mvControlling->MainCtrlPos ].Mn == 0 ) { while( ( mvControlling->RList[ mvControlling->MainCtrlPos ].Mn == 0 )
mvControlling->IncMainCtrl( 1 ); && ( mvControlling->IncMainCtrl( 1 ) ) ) {
;
} }
} }
if( ( mvControlling->EnginePowerSource.SourceType != TPowerSource::CurrentCollector ) if( ( mvControlling->EnginePowerSource.SourceType != TPowerSource::CurrentCollector )
@@ -2562,9 +2556,7 @@ bool TController::ReleaseEngine() {
VelDesired = 0.0; VelDesired = 0.0;
AccDesired = std::min( AccDesired, -1.25 ); // hamuj solidnie AccDesired = std::min( AccDesired, -1.25 ); // hamuj solidnie
ReactionTime = 0.1; ReactionTime = 0.1;
while( DecSpeed( true ) ) { ZeroSpeed();
; // zerowanie nastawników
}
IncBrake(); IncBrake();
// don't bother with the rest until we're standing still // don't bother with the rest until we're standing still
return false; return false;
@@ -2601,12 +2593,8 @@ bool TController::ReleaseEngine() {
; ;
} }
} }
while( DecSpeed( true ) ) { ZeroSpeed();
; // zerowanie nastawników ZeroDirection();
}
// set direction to neutral
while( ( mvOccupied->ActiveDir > 0 ) && ( mvOccupied->DirectionBackward() ) ) { ; }
while( ( mvOccupied->ActiveDir < 0 ) && ( mvOccupied->DirectionForward() ) ) { ; }
// zamykanie drzwi // zamykanie drzwi
mvOccupied->OperateDoors( side::right, false ); mvOccupied->OperateDoors( side::right, false );
@@ -2948,7 +2936,7 @@ bool TController::IncSpeed()
return false; // to nici z ruszania return false; // to nici z ruszania
} }
if (!mvControlling->FuseFlag) //&&mvControlling->StLinFlag) //yBARC if (!mvControlling->FuseFlag) //&&mvControlling->StLinFlag) //yBARC
if ((mvControlling->MainCtrlPos == 0) || if ((mvControlling->IsMainCtrlZero()) ||
(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)) {
@@ -3030,7 +3018,7 @@ bool TController::IncSpeed()
} }
if( ( mvControlling->Im == 0 ) if( ( mvControlling->Im == 0 )
&& ( mvControlling->MainCtrlPos > 2 ) ) { && ( mvControlling->MainCtrlPowerPos() > 1 ) ) {
// brak prądu na dalszych pozycjach // brak prądu na dalszych pozycjach
// nie załączona lokomotywa albo wywalił nadmiarowy // nie załączona lokomotywa albo wywalił nadmiarowy
Need_TryAgain = true; Need_TryAgain = true;
@@ -3098,6 +3086,24 @@ bool TController::IncSpeed()
return OK; return OK;
} }
void TController::ZeroSpeed( bool const Enforce ) {
while( DecSpeed( Enforce ) ) {
;
}
}
void TController::ZeroMasterController( bool const Enforce ) {
// combined controller may be set to braking, i.e. position lower than neutral
auto const neutralposition { mvControlling->MainCtrlZeroPos() };
while( ( mvControlling->MainCtrlPos < neutralposition )
&& ( DecBrake() ) ) {
;
}
ZeroSpeed( Enforce );
}
bool TController::DecSpeed(bool force) bool TController::DecSpeed(bool force)
{ // 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
@@ -3107,20 +3113,20 @@ bool TController::DecSpeed(bool force)
iDrivigFlags &= ~moveIncSpeed; // usunięcie flagi jazdy iDrivigFlags &= ~moveIncSpeed; // usunięcie flagi jazdy
if (force) // przy aktywacji kabiny jest potrzeba natychmiastowego wyzerowania if (force) // przy aktywacji kabiny jest potrzeba natychmiastowego wyzerowania
if (mvControlling->MainCtrlPosNo > 0) // McZapkie-041003: wagon sterowniczy, np. EZT if (mvControlling->MainCtrlPosNo > 0) // McZapkie-041003: wagon sterowniczy, np. EZT
mvControlling->DecMainCtrl(1 + (mvControlling->MainCtrlPos > 2 ? 1 : 0)); mvControlling->DecMainCtrl((mvControlling->MainCtrlPowerPos() > 1 ? 2 : 1));
mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania
return false; return false;
case TEngineType::ElectricSeriesMotor: case TEngineType::ElectricSeriesMotor:
OK = mvControlling->DecScndCtrl(2); // najpierw bocznik na zero OK = mvControlling->DecScndCtrl(2); // najpierw bocznik na zero
if (!OK) if (!OK)
OK = mvControlling->DecMainCtrl(1 + (mvControlling->MainCtrlPos > 2 ? 1 : 0)); OK = mvControlling->DecMainCtrl((mvControlling->MainCtrlPowerPos() > 1 ? 2 : 1));
mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania
break; break;
case TEngineType::Dumb: case TEngineType::Dumb:
case TEngineType::DieselElectric: case TEngineType::DieselElectric:
OK = mvControlling->DecScndCtrl(2); OK = mvControlling->DecScndCtrl(2);
if (!OK) if (!OK)
OK = mvControlling->DecMainCtrl(2 + (mvControlling->MainCtrlPos / 2)); OK = mvControlling->DecMainCtrl(2 + (mvControlling->MainCtrlPowerPos() / 2));
break; break;
case TEngineType::ElectricInductionMotor: case TEngineType::ElectricInductionMotor:
OK = DecSpeedEIM(); OK = DecSpeedEIM();
@@ -3139,12 +3145,14 @@ bool TController::DecSpeed(bool force)
if (mvControlling->RList[mvControlling->MainCtrlPos].Mn > 0) if (mvControlling->RList[mvControlling->MainCtrlPos].Mn > 0)
OK = mvControlling->DecMainCtrl(1); OK = mvControlling->DecMainCtrl(1);
} }
else else {
while ((mvControlling->RList[mvControlling->MainCtrlPos].Mn > 0) && while( ( mvControlling->RList[ mvControlling->MainCtrlPos ].Mn > 0 )
(mvControlling->MainCtrlPos > 1)) && ( mvControlling->MainCtrlPowerPos() > 1 ) ) {
OK = mvControlling->DecMainCtrl(1); OK = mvControlling->DecMainCtrl( 1 );
}
}
if (force) // przy aktywacji kabiny jest potrzeba natychmiastowego wyzerowania if (force) // przy aktywacji kabiny jest potrzeba natychmiastowego wyzerowania
OK = mvControlling->DecMainCtrl(1 + (mvControlling->MainCtrlPos > 2 ? 1 : 0)); OK = mvControlling->DecMainCtrl((mvControlling->MainCtrlPowerPos() > 2 ? 2 : 1));
break; break;
} }
return OK; return OK;
@@ -3244,8 +3252,7 @@ void TController::SpeedSet()
if( ( false == mvControlling->StLinFlag ) if( ( false == mvControlling->StLinFlag )
&& ( false == mvControlling->DelayCtrlFlag ) ) { && ( false == mvControlling->DelayCtrlFlag ) ) {
// styczniki liniowe rozłączone yBARC // styczniki liniowe rozłączone yBARC
while( DecSpeed() ) ZeroSpeed();
; // zerowanie napędu
} }
else if (Ready || (iDrivigFlags & movePress)) // o ile może jechać else 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
@@ -4113,7 +4120,7 @@ TController::UpdateSituation(double dt) {
// for others straightforward master controller check // for others straightforward master controller check
if( ( mvControlling->EngineType == TEngineType::DieselEngine ? if( ( mvControlling->EngineType == TEngineType::DieselEngine ?
mvControlling->RList[ mvControlling->MainCtrlPos ].Mn > 0 : mvControlling->RList[ mvControlling->MainCtrlPos ].Mn > 0 :
mvControlling->MainCtrlPos > 0 ) ) { mvControlling->MainCtrlPowerPos() > 0 ) ) {
Doors( false ); Doors( false );
} }
} }
@@ -4176,7 +4183,7 @@ TController::UpdateSituation(double dt) {
// is moving // is moving
if( ( fOverhead2 >= 0.0 ) || iOverheadZero ) { if( ( fOverhead2 >= 0.0 ) || iOverheadZero ) {
// jeśli jazda bezprądowa albo z opuszczonym pantografem // jeśli jazda bezprądowa albo z opuszczonym pantografem
while( DecSpeed( true ) ) { ; } // zerowanie napędu ZeroSpeed();
} }
if( ( fOverhead2 > 0.0 ) || iOverheadDown ) { if( ( fOverhead2 > 0.0 ) || iOverheadDown ) {
// jazda z opuszczonymi pantografami // jazda z opuszczonymi pantografami
@@ -4272,7 +4279,7 @@ TController::UpdateSituation(double dt) {
if( ( true == TestFlag( iDrivigFlags, moveStartHornNow ) ) if( ( true == TestFlag( iDrivigFlags, moveStartHornNow ) )
&& ( true == Ready ) && ( true == Ready )
&& ( iEngineActive != 0 ) && ( iEngineActive != 0 )
&& ( mvControlling->MainCtrlPos > 0 ) ) { && ( mvControlling->MainCtrlPowerPos() > 0 ) ) {
// uruchomienie trąbienia przed ruszeniem // uruchomienie trąbienia przed ruszeniem
fWarningDuration = 0.3; // czas trąbienia fWarningDuration = 0.3; // czas trąbienia
mvOccupied->WarningSignal = pVehicle->iHornWarning; // wysokość tonu (2=wysoki) mvOccupied->WarningSignal = pVehicle->iHornWarning; // wysokość tonu (2=wysoki)
@@ -4792,7 +4799,7 @@ TController::UpdateSituation(double dt) {
// jeśli dociskanie w celu odczepienia // jeśli dociskanie w celu odczepienia
// 3. faza odczepiania. // 3. faza odczepiania.
SetVelocity(2, 0); // jazda w ustawionym kierunku z prędkością 2 SetVelocity(2, 0); // jazda w ustawionym kierunku z prędkością 2
if( ( mvControlling->MainCtrlPos > 0 ) if( ( mvControlling->MainCtrlPowerPos() > 0 )
|| ( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) ) { || ( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) ) {
// jeśli jazda // jeśli jazda
WriteLog(mvOccupied->Name + " odczepianie w kierunku " + std::to_string(mvOccupied->DirAbsolute)); WriteLog(mvOccupied->Name + " odczepianie w kierunku " + std::to_string(mvOccupied->DirAbsolute));
@@ -4883,16 +4890,15 @@ TController::UpdateSituation(double dt) {
if (iDrivigFlags & movePress) if (iDrivigFlags & movePress)
{ // 4. faza odczepiania: zwolnij i zmień kierunek { // 4. faza odczepiania: zwolnij i zmień kierunek
SetVelocity(0, 0, stopJoin); // wyłączyć przyspieszanie SetVelocity(0, 0, stopJoin); // wyłączyć przyspieszanie
if (!DecSpeed()) // jeśli już bardziej wyłączyć się nie da ZeroSpeed();
{ // ponowna zmiana kierunku // ponowna zmiana kierunku
WriteLog( mvOccupied->Name + " ponowna zmiana kierunku" ); WriteLog( mvOccupied->Name + " ponowna zmiana kierunku" );
DirectionForward(mvOccupied->ActiveDir < 0); // zmiana kierunku jazdy na właściwy DirectionForward(mvOccupied->ActiveDir < 0); // zmiana kierunku jazdy na właściwy
iDrivigFlags &= ~movePress; // koniec dociskania iDrivigFlags &= ~movePress; // koniec dociskania
JumpToNextOrder(); // zmieni światła JumpToNextOrder(); // zmieni światła
TableClear(); // skanowanie od nowa TableClear(); // skanowanie od nowa
iDrivigFlags &= ~moveStartHorn; // bez trąbienia przed ruszeniem iDrivigFlags &= ~moveStartHorn; // bez trąbienia przed ruszeniem
SetVelocity(fShuntVelocity, fShuntVelocity); // ustawienie prędkości jazdy SetVelocity(fShuntVelocity, fShuntVelocity); // ustawienie prędkości jazdy
}
} }
} }
@@ -5458,7 +5464,7 @@ TController::UpdateSituation(double dt) {
if( ( true == mvOccupied->RadioStopFlag ) // radio-stop if( ( true == mvOccupied->RadioStopFlag ) // radio-stop
&& ( mvOccupied->Vel > 0.0 ) ) { // and still moving && ( mvOccupied->Vel > 0.0 ) ) { // and still moving
// if the radio-stop was issued don't waste effort trying to fight it // if the radio-stop was issued don't waste effort trying to fight it
while( true == DecSpeed() ) { ; } // just throttle down... ZeroSpeed(); // just throttle down...
return; // ...and don't touch any other controls return; // ...and don't touch any other controls
} }
@@ -5622,7 +5628,7 @@ TController::UpdateSituation(double dt) {
if( false == TestFlag( iDrivigFlags, movePress ) ) { if( false == TestFlag( iDrivigFlags, movePress ) ) {
// jeśli nie dociskanie // jeśli nie dociskanie
if( AccDesired < -0.05 ) { if( AccDesired < -0.05 ) {
while( true == DecSpeed() ) { ; } // jeśli hamujemy, to nie przyspieszamy ZeroSpeed();
} }
else if( ( vel > VelDesired ) else if( ( vel > VelDesired )
|| ( fAccGravity < -0.01 ? || ( fAccGravity < -0.01 ?
@@ -6411,21 +6417,35 @@ void TController::TakeControl(bool yes)
void TController::DirectionForward(bool forward) void TController::DirectionForward(bool forward)
{ // ustawienie jazdy do przodu dla true i do tyłu dla false (zależy od kabiny) { // ustawienie jazdy do przodu dla true i do tyłu dla false (zależy od kabiny)
while (mvControlling->MainCtrlPos) // samo zapętlenie DecSpeed() nie wystarcza ZeroSpeed( true ); // TODO: check if force switch is needed anymore here
DecSpeed(true); // wymuszenie zerowania nastawnika jazdy, inaczej się może zawiesić if( forward ) {
if (forward) // do przodu w obecnej kabinie
while (mvOccupied->ActiveDir <= 0) while( ( mvOccupied->ActiveDir <= 0 )
mvOccupied->DirectionForward(); // do przodu w obecnej kabinie && ( mvOccupied->DirectionForward() ) ) {
else ; // all work is done in the header
while (mvOccupied->ActiveDir >= 0)
mvOccupied->DirectionBackward(); // do tyłu w obecnej kabinie
if( mvOccupied->TrainType == dt_SN61 ) {
// specjalnie dla SN61 żeby nie zgasł
if( mvControlling->RList[ mvControlling->MainCtrlPos ].Mn == 0 ) {
mvControlling->IncMainCtrl( 1 );
} }
} }
}; else {
// do tyłu w obecnej kabinie
while( ( mvOccupied->ActiveDir >= 0 )
&& ( mvOccupied->DirectionBackward() ) ) {
; // all work is done in the header
}
}
if( mvOccupied->TrainType == dt_SN61 ) {
// specjalnie dla SN61 żeby nie zgasł
while( ( mvControlling->RList[ mvControlling->MainCtrlPos ].Mn == 0 )
&& ( mvControlling->IncMainCtrl( 1 ) ) ) {
; // all work is done in the header
}
}
}
void TController::ZeroDirection() {
while( ( mvOccupied->ActiveDir > 0 ) && ( mvOccupied->DirectionBackward() ) ) { ; }
while( ( mvOccupied->ActiveDir < 0 ) && ( mvOccupied->DirectionForward() ) ) { ; }
}
Mtable::TTrainParameters const * Mtable::TTrainParameters const *
TController::TrainTimetable() const { TController::TrainTimetable() const {

View File

@@ -211,6 +211,8 @@ private:
bool DecBrake(); bool DecBrake();
bool IncSpeed(); bool IncSpeed();
bool DecSpeed(bool force = false); bool DecSpeed(bool force = false);
void ZeroSpeed( bool const Enforce = false );
void ZeroMasterController( bool const Enforce = false );
bool IncBrakeEIM(); bool IncBrakeEIM();
bool DecBrakeEIM(); bool DecBrakeEIM();
bool IncSpeedEIM(); bool IncSpeedEIM();
@@ -224,6 +226,7 @@ private:
int CheckDirection(); int CheckDirection();
void WaitingSet(double Seconds); void WaitingSet(double Seconds);
void DirectionForward(bool forward); void DirectionForward(bool forward);
void ZeroDirection();
int OrderDirectionChange(int newdir, TMoverParameters *Vehicle); int OrderDirectionChange(int newdir, TMoverParameters *Vehicle);
void Lights(int head, int rear); void Lights(int head, int rear);
std::string StopReasonText() const; std::string StopReasonText() const;

View File

@@ -1591,6 +1591,8 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
Error("Parameters mismatch: dynamic object " + asName + " from \"" + BaseDir + "/" + Type_Name + "\"" ); Error("Parameters mismatch: dynamic object " + asName + " from \"" + BaseDir + "/" + Type_Name + "\"" );
return 0.0; // zerowa długość to brak pojazdu return 0.0; // zerowa długość to brak pojazdu
} }
// controller position
MoverParameters->MainCtrlPos = MoverParameters->MainCtrlZeroPos();
// ustawienie pozycji hamulca // ustawienie pozycji hamulca
MoverParameters->LocalBrakePosA = 0.0; MoverParameters->LocalBrakePosA = 0.0;
if (driveractive) if (driveractive)
@@ -2969,7 +2971,7 @@ bool TDynamicObject::Update(double dt, double dt1)
} }
MEDLogTime += dt1; MEDLogTime += dt1;
if ((MoverParameters->Vel < 0.1) || (MoverParameters->MainCtrlPos > 0)) if ((MoverParameters->Vel < 0.1) || (MoverParameters->MainCtrlPowerPos() > 0))
{ {
MEDLogInactiveTime += dt1; MEDLogInactiveTime += dt1;
} }

View File

@@ -1392,6 +1392,9 @@ public:
/*! glowny nastawnik:*/ /*! glowny nastawnik:*/
bool IncMainCtrl(int CtrlSpeed); bool IncMainCtrl(int CtrlSpeed);
bool DecMainCtrl(int CtrlSpeed); bool DecMainCtrl(int CtrlSpeed);
bool IsMainCtrlZero() const;
int MainCtrlZeroPos() const;
int MainCtrlPowerPos() const;
/*! pomocniczy nastawnik:*/ /*! pomocniczy nastawnik:*/
bool IncScndCtrl(int CtrlSpeed); bool IncScndCtrl(int CtrlSpeed);
bool DecScndCtrl(int CtrlSpeed); bool DecScndCtrl(int CtrlSpeed);

View File

@@ -502,7 +502,7 @@ bool TMoverParameters::Dettach(int ConnectNo)
bool TMoverParameters::DirectionForward() bool TMoverParameters::DirectionForward()
{ {
if ((MainCtrlPosNo > 0) && (ActiveDir < 1) && (MainCtrlPos == 0)) if ((MainCtrlPosNo > 0) && (ActiveDir < 1) && (IsMainCtrlZero()))
{ {
++ActiveDir; ++ActiveDir;
DirAbsolute = ActiveDir * CabNo; DirAbsolute = ActiveDir * CabNo;
@@ -512,7 +512,7 @@ bool TMoverParameters::DirectionForward()
SendCtrlToNext("Direction", ActiveDir, CabNo); SendCtrlToNext("Direction", ActiveDir, CabNo);
return true; return true;
} }
else if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor)) else if ((ActiveDir == 1) && (IsMainCtrlZero()) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor))
return MinCurrentSwitch(true); //"wysoki rozruch" EN57 return MinCurrentSwitch(true); //"wysoki rozruch" EN57
return false; return false;
}; };
@@ -641,7 +641,7 @@ TMoverParameters::CurrentSwitch(bool const State) {
// for SM42/SP42 // for SM42/SP42
if( ( EngineType == TEngineType::DieselElectric ) if( ( EngineType == TEngineType::DieselElectric )
&& ( true == ShuntModeAllow ) && ( true == ShuntModeAllow )
&& ( MainCtrlPos == 0 ) ) { && ( IsMainCtrlZero() ) ) {
ShuntMode = State; ShuntMode = State;
return true; return true;
} }
@@ -1732,17 +1732,17 @@ bool TMoverParameters::IncMainCtrl(int CtrlSpeed)
case TEngineType::DieselEngine: case TEngineType::DieselEngine:
{ {
if( CtrlSpeed > 1 ) { if( CtrlSpeed > 1 ) {
while( MainCtrlPos < MainCtrlPosNo ) { while( ( MainCtrlPos < MainCtrlPosNo )
IncMainCtrl( 1 ); && ( IncMainCtrl( 1 ) ) ) {
;
}
} }
else {
++MainCtrlPos;
} }
else { CompressorAllow = ( MainCtrlPowerPos() > 0 );
++MainCtrlPos; OK = true;
if( MainCtrlPos > 0 ) { CompressorAllow = true; }
else { CompressorAllow = false; }
}
OK = true;
break; break;
} }
@@ -1805,6 +1805,7 @@ bool TMoverParameters::DecMainCtrl(int CtrlSpeed)
} }
else else
{ {
// TBD, TODO: replace with mainctrlpowerpos() check?
if (MainCtrlPos > 0) if (MainCtrlPos > 0)
{ {
if ((TrainType != dt_ET22) || if ((TrainType != dt_ET22) ||
@@ -1903,6 +1904,25 @@ bool TMoverParameters::DecMainCtrl(int CtrlSpeed)
return OK; return OK;
} }
bool TMoverParameters::IsMainCtrlZero() const {
// TODO: wrap controller pieces into a class for potential specializations, similar to brake subsystems
return MainCtrlPos == MainCtrlZeroPos();
}
int TMoverParameters::MainCtrlZeroPos() const {
switch( EIMCtrlType ) {
case 1: { return 4; }
case 2: { return 2; }
default: { return 0; }
}
}
int TMoverParameters::MainCtrlPowerPos() const {
return MainCtrlPos - MainCtrlZeroPos();
}
// ************************************************************************************************* // *************************************************************************************************
// Q: 20160710 // Q: 20160710
// zwiększenie bocznika // zwiększenie bocznika
@@ -1911,14 +1931,13 @@ bool TMoverParameters::IncScndCtrl(int CtrlSpeed)
{ {
bool OK = false; bool OK = false;
if ((MainCtrlPos == 0) && (CabNo != 0) && (TrainType == dt_ET42) && (ScndCtrlPos == 0) && if ((IsMainCtrlZero()) && (CabNo != 0) && (TrainType == dt_ET42) && (ScndCtrlPos == 0) && (DynamicBrakeFlag))
(DynamicBrakeFlag))
{ {
OK = DynamicBrakeSwitch(false); OK = DynamicBrakeSwitch(false);
} }
else if ((ScndCtrlPosNo > 0) && (CabNo != 0) && else if ((ScndCtrlPosNo > 0) && (CabNo != 0) &&
!((TrainType == dt_ET42) && !((TrainType == dt_ET42) &&
((Imax == ImaxHi) || ((DynamicBrakeFlag) && (MainCtrlPos > 0))))) ((Imax == ImaxHi) || ((DynamicBrakeFlag) && (MainCtrlPowerPos() > 0)))))
{ {
// if (RList[MainCtrlPos].R=0) and (MainCtrlPos>0) and (ScndCtrlPos<ScndCtrlPosNo) and // if (RList[MainCtrlPos].R=0) and (MainCtrlPos>0) and (ScndCtrlPos<ScndCtrlPosNo) and
// (not CoupledCtrl) then // (not CoupledCtrl) then
@@ -1973,7 +1992,7 @@ bool TMoverParameters::DecScndCtrl(int CtrlSpeed)
{ {
bool OK = false; bool OK = false;
if ((MainCtrlPos == 0) && (CabNo != 0) && (TrainType == dt_ET42) && (ScndCtrlPos == 0) && if ((IsMainCtrlZero()) && (CabNo != 0) && (TrainType == dt_ET42) && (ScndCtrlPos == 0) &&
!(DynamicBrakeFlag) && (CtrlSpeed == 1)) !(DynamicBrakeFlag) && (CtrlSpeed == 1))
{ {
// Ra: AI wywołuje z CtrlSpeed=2 albo gdy ScndCtrlPos>0 // Ra: AI wywołuje z CtrlSpeed=2 albo gdy ScndCtrlPos>0
@@ -2320,13 +2339,16 @@ bool TMoverParameters::EpFuseSwitch(bool State)
bool TMoverParameters::DirectionBackward(void) bool TMoverParameters::DirectionBackward(void)
{ {
bool DB = false; bool DB = false;
if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor)) if ( ( TrainType == dt_EZT )
&& ( EngineType != TEngineType::ElectricInductionMotor )
&& ( ActiveDir == 1 )
&& (IsMainCtrlZero() ) )
if (MinCurrentSwitch(false)) if (MinCurrentSwitch(false))
{ {
DB = true; // DB = true; //
return DB; // exit; TODO: czy dobrze przetlumaczone? return DB; // exit; TODO: czy dobrze przetlumaczone?
} }
if ((MainCtrlPosNo > 0) && (ActiveDir > -1) && (MainCtrlPos == 0)) if ((MainCtrlPosNo > 0) && (ActiveDir > -1) && (IsMainCtrlZero()))
{ {
if (EngineType == TEngineType::WheelsDriven) if (EngineType == TEngineType::WheelsDriven)
CabNo--; CabNo--;
@@ -2946,7 +2968,7 @@ bool TMoverParameters::DynamicBrakeSwitch(bool Switch)
{ {
bool DBS; bool DBS;
if ((DynamicBrakeType == dbrake_switch) && (MainCtrlPos == 0)) if ((DynamicBrakeType == dbrake_switch) && (IsMainCtrlZero()))
{ {
DynamicBrakeFlag = Switch; DynamicBrakeFlag = Switch;
DBS = true; DBS = true;
@@ -3240,7 +3262,7 @@ void TMoverParameters::CompressorCheck(double dt)
if( ( true == CompressorAllow ) if( ( true == CompressorAllow )
&& ( true == CompressorAllowLocal ) && ( true == CompressorAllowLocal )
&& ( true == Mains ) && ( true == Mains )
&& ( MainCtrlPos > 0 ) ) { && ( MainCtrlPowerPos() > 0 ) ) {
if( Compressor < MaxCompressor ) { if( Compressor < MaxCompressor ) {
if( ( EngineType == TEngineType::DieselElectric ) if( ( EngineType == TEngineType::DieselElectric )
&& ( CompressorPower > 0 ) ) { && ( CompressorPower > 0 ) ) {
@@ -4489,7 +4511,7 @@ double TMoverParameters::TractionForce( double dt ) {
} }
case TEngineType::DieselEngine: { case TEngineType::DieselEngine: {
EnginePower = ( 2 * dizel_Mstand + dmoment ) * enrot * ( 2.0 * M_PI / 1000.0 ); EnginePower = ( 2 * dizel_Mstand + dmoment ) * enrot * ( 2.0 * M_PI / 1000.0 );
if( MainCtrlPos > 1 ) { if( MainCtrlPowerPos() > 1 ) {
// dodatkowe opory z powodu sprezarki} // dodatkowe opory z powodu sprezarki}
dmoment -= dizel_Mstand * ( 0.2 * enrot / dizel_nmax ); dmoment -= dizel_Mstand * ( 0.2 * enrot / dizel_nmax );
} }
@@ -4686,7 +4708,7 @@ double TMoverParameters::TractionForce( double dt ) {
auto const tmpV { nrot * Pirazy2 * 0.5 * WheelDiameter * DirAbsolute }; //*CabNo*ActiveDir; auto const tmpV { nrot * Pirazy2 * 0.5 * WheelDiameter * DirAbsolute }; //*CabNo*ActiveDir;
// jazda manewrowa // jazda manewrowa
if( true == ShuntMode ) { if( true == ShuntMode ) {
if( ( true == Mains ) && ( MainCtrlPos > 0 ) ) { if( ( true == Mains ) && ( MainCtrlPowerPos() > 0 ) ) {
Voltage = ( SST[ MainCtrlPos ].Umax * AnPos ) + ( SST[ MainCtrlPos ].Umin * ( 1.0 - AnPos ) ); Voltage = ( SST[ MainCtrlPos ].Umax * AnPos ) + ( SST[ MainCtrlPos ].Umin * ( 1.0 - AnPos ) );
// NOTE: very crude way to approximate power generated at current rpm instead of instant top output // NOTE: very crude way to approximate power generated at current rpm instead of instant top output
// NOTE, TODO: doesn't take into account potentially increased revolutions if heating is on, fix it // NOTE, TODO: doesn't take into account potentially increased revolutions if heating is on, fix it
@@ -4717,7 +4739,7 @@ double TMoverParameters::TractionForce( double dt ) {
PosRatio = currentgenpower / DElist[MainCtrlPosNo].GenPower; PosRatio = currentgenpower / DElist[MainCtrlPosNo].GenPower;
// stosunek mocy teraz do mocy max // stosunek mocy teraz do mocy max
// NOTE: Mains in this context is working diesel engine // NOTE: Mains in this context is working diesel engine
if( ( true == Mains ) && ( MainCtrlPos > 0 ) ) { if( ( true == Mains ) && ( MainCtrlPowerPos() > 0 ) ) {
if( tmpV < ( Vhyp * power / DElist[ MainCtrlPosNo ].GenPower ) ) { if( tmpV < ( Vhyp * power / DElist[ MainCtrlPosNo ].GenPower ) ) {
// czy na czesci prostej, czy na hiperboli // czy na czesci prostej, czy na hiperboli
@@ -4819,7 +4841,7 @@ double TMoverParameters::TractionForce( double dt ) {
Voltage = 0; Voltage = 0;
// przekazniki bocznikowania, kazdy inny dla kazdej pozycji // przekazniki bocznikowania, kazdy inny dla kazdej pozycji
if ((MainCtrlPos == 0) || (ShuntMode) || (false==Mains)) if ((IsMainCtrlZero()) || (ShuntMode) || (false==Mains))
ScndCtrlPos = 0; ScndCtrlPos = 0;
else { else {
@@ -5302,7 +5324,7 @@ bool TMoverParameters::FuseFlagCheck(void) const
bool TMoverParameters::FuseOn(void) bool TMoverParameters::FuseOn(void)
{ {
bool FO = false; bool FO = false;
if ((MainCtrlPos == 0) && (ScndCtrlPos == 0) && (TrainType != dt_ET40) && if ((IsMainCtrlZero()) && (ScndCtrlPos == 0) && (TrainType != dt_ET40) &&
((Mains) || (TrainType != dt_EZT)) && (!TestFlag(EngDmgFlag, 1))) ((Mains) || (TrainType != dt_EZT)) && (!TestFlag(EngDmgFlag, 1)))
{ // w ET40 jest blokada nastawnika, ale czy działa dobrze? { // w ET40 jest blokada nastawnika, ale czy działa dobrze?
SendCtrlToNext("FuseSwitch", 1, CabNo); SendCtrlToNext("FuseSwitch", 1, CabNo);
@@ -5790,7 +5812,7 @@ bool TMoverParameters::MotorConnectorsCheck() {
( false == Mains ) ( false == Mains )
|| ( true == FuseFlag ) || ( true == FuseFlag )
|| ( true == StLinSwitchOff ) || ( true == StLinSwitchOff )
|| ( MainCtrlPos == 0 ) || ( IsMainCtrlZero() )
|| ( ActiveDir == 0 ) }; || ( ActiveDir == 0 ) };
if( connectorsoff ) { return false; } if( connectorsoff ) { return false; }
@@ -5798,8 +5820,9 @@ bool TMoverParameters::MotorConnectorsCheck() {
auto const connectorson { auto const connectorson {
( true == StLinFlag ) ( true == StLinFlag )
|| ( ( MainCtrlActualPos == 0 ) || ( ( MainCtrlActualPos == 0 )
&& ( ( MainCtrlPos == 1 ) && ( ( TrainType != dt_EZT ?
|| ( ( TrainType == dt_EZT ) && ( MainCtrlPos > 0 ) ) ) ) }; MainCtrlPowerPos() == 1 :
MainCtrlPowerPos() > 0 ) ) ) };
return connectorson; return connectorson;
} }
@@ -6047,7 +6070,7 @@ bool TMoverParameters::dizel_AutoGearCheck(void)
{ {
if (dizel_engagestate > 0) if (dizel_engagestate > 0)
dizel_EngageSwitch(0); dizel_EngageSwitch(0);
if ((MainCtrlPos == 0) && (ScndCtrlActualPos > 0)) if ((IsMainCtrlZero()) && (ScndCtrlActualPos > 0))
dizel_automaticgearstatus = -1; dizel_automaticgearstatus = -1;
} }
else else
@@ -6331,10 +6354,10 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
if (hydro_TC) //jesli przetwornik momentu if (hydro_TC) //jesli przetwornik momentu
{ {
//napelnianie przetwornika //napelnianie przetwornika
if ((MainCtrlPos > 0) && (Mains) && (enrot>dizel_nmin*0.9)) if ((MainCtrlPowerPos() > 0) && (Mains) && (enrot>dizel_nmin*0.9))
hydro_TC_Fill += hydro_TC_FillRateInc * dt; hydro_TC_Fill += hydro_TC_FillRateInc * dt;
//oproznianie przetwornika //oproznianie przetwornika
if (((MainCtrlPos == 0) && (Vel<3)) if (((IsMainCtrlZero()) && (Vel<3))
|| (!Mains) || (!Mains)
|| (enrot<dizel_nmin*0.8)) || (enrot<dizel_nmin*0.8))
hydro_TC_Fill -= hydro_TC_FillRateDec * dt; hydro_TC_Fill -= hydro_TC_FillRateDec * dt;
@@ -6342,10 +6365,10 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
hydro_TC_Fill = clamp(hydro_TC_Fill, 0.0, 1.0); hydro_TC_Fill = clamp(hydro_TC_Fill, 0.0, 1.0);
//blokowanie sprzegla blokującego //blokowanie sprzegla blokującego
if ((Vel > hydro_TC_LockupSpeed) && (Mains) && (enrot > 0.9 * dizel_nmin) && (MainCtrlPos>0)) if ((Vel > hydro_TC_LockupSpeed) && (Mains) && (enrot > 0.9 * dizel_nmin) && (MainCtrlPowerPos() > 0))
hydro_TC_LockupRate += hydro_TC_FillRateInc*dt; hydro_TC_LockupRate += hydro_TC_FillRateInc*dt;
//luzowanie sprzegla blokujacego //luzowanie sprzegla blokujacego
if ((Vel < (MainCtrlPos>0 ? hydro_TC_LockupSpeed : hydro_TC_UnlockSpeed)) || (!Mains) || (enrot < 0.8 * dizel_nmin)) if ((Vel < (MainCtrlPowerPos() > 0 ? hydro_TC_LockupSpeed : hydro_TC_UnlockSpeed)) || (!Mains) || (enrot < 0.8 * dizel_nmin))
hydro_TC_LockupRate -= hydro_TC_FillRateDec*dt; hydro_TC_LockupRate -= hydro_TC_FillRateDec*dt;
//obcinanie zakresu //obcinanie zakresu
hydro_TC_LockupRate = clamp(hydro_TC_LockupRate, 0.0, 1.0); hydro_TC_LockupRate = clamp(hydro_TC_LockupRate, 0.0, 1.0);

View File

@@ -782,8 +782,8 @@ void TTrain::OnCommand_jointcontrollerset( TTrain *Train, command_data const &Co
clamp( clamp(
1.0 - ( Command.param1 * 2 ), 1.0 - ( Command.param1 * 2 ),
0.0, 1.0 ) ); 0.0, 1.0 ) );
if( Train->mvControlled->MainCtrlPos > 0 ) { if( Train->mvControlled->MainCtrlPowerPos() > 0 ) {
Train->set_master_controller( 0 ); Train->set_master_controller( Train->mvControlled->MainCtrlZeroPos() );
} }
} }
} }
@@ -839,7 +839,7 @@ void TTrain::OnCommand_mastercontrollerdecrease( TTrain *Train, command_data con
if( Command.action != GLFW_RELEASE ) { if( Command.action != GLFW_RELEASE ) {
// on press or hold // on press or hold
if( ( Train->ggJointCtrl.SubModel != nullptr ) if( ( Train->ggJointCtrl.SubModel != nullptr )
&& ( Train->mvControlled->MainCtrlPos == 0 ) ) { && ( Train->mvControlled->IsMainCtrlZero() ) ) {
OnCommand_independentbrakeincrease( Train, Command ); OnCommand_independentbrakeincrease( Train, Command );
} }
else { else {
@@ -859,7 +859,7 @@ void TTrain::OnCommand_mastercontrollerdecreasefast( TTrain *Train, command_data
if( Command.action != GLFW_RELEASE ) { if( Command.action != GLFW_RELEASE ) {
// on press or hold // on press or hold
if( ( Train->ggJointCtrl.SubModel != nullptr ) if( ( Train->ggJointCtrl.SubModel != nullptr )
&& ( Train->mvControlled->MainCtrlPos == 0 ) ) { && ( Train->mvControlled->IsMainCtrlZero() ) ) {
OnCommand_independentbrakeincreasefast( Train, Command ); OnCommand_independentbrakeincreasefast( Train, Command );
} }
else { else {