mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
Merge branch 'tmj-dev' into milek-dev
This commit is contained in:
@@ -244,24 +244,10 @@ void TAnimContainer::UpdateModel() {
|
||||
}
|
||||
if (fRotateSpeed != 0.0)
|
||||
{
|
||||
|
||||
/*
|
||||
double dif= fDesiredAngle-fAngle;
|
||||
double s= fRotateSpeed*sign(dif)*Timer::GetDeltaTime();
|
||||
if ((abs(s)-abs(dif))>0)
|
||||
fAngle= fDesiredAngle;
|
||||
else
|
||||
fAngle+= s;
|
||||
|
||||
while (fAngle>360) fAngle-= 360;
|
||||
while (fAngle<-360) fAngle+= 360;
|
||||
pSubModel->SetRotate(vRotateAxis,fAngle);
|
||||
*/
|
||||
|
||||
bool anim = false;
|
||||
auto dif = vDesiredAngles - vRotateAngles;
|
||||
double s;
|
||||
s = fRotateSpeed * sign(dif.x) * Timer::GetDeltaTime();
|
||||
s = std::abs( fRotateSpeed ) * sign(dif.x) * Timer::GetDeltaTime();
|
||||
if (fabs(s) >= fabs(dif.x))
|
||||
vRotateAngles.x = vDesiredAngles.x;
|
||||
else
|
||||
@@ -269,7 +255,7 @@ void TAnimContainer::UpdateModel() {
|
||||
vRotateAngles.x += s;
|
||||
anim = true;
|
||||
}
|
||||
s = fRotateSpeed * sign(dif.y) * Timer::GetDeltaTime();
|
||||
s = std::abs( fRotateSpeed ) * sign(dif.y) * Timer::GetDeltaTime();
|
||||
if (fabs(s) >= fabs(dif.y))
|
||||
vRotateAngles.y = vDesiredAngles.y;
|
||||
else
|
||||
@@ -277,7 +263,7 @@ void TAnimContainer::UpdateModel() {
|
||||
vRotateAngles.y += s;
|
||||
anim = true;
|
||||
}
|
||||
s = fRotateSpeed * sign(dif.z) * Timer::GetDeltaTime();
|
||||
s = std::abs( fRotateSpeed ) * sign(dif.z) * Timer::GetDeltaTime();
|
||||
if (fabs(s) >= fabs(dif.z))
|
||||
vRotateAngles.z = vDesiredAngles.z;
|
||||
else
|
||||
@@ -285,22 +271,27 @@ void TAnimContainer::UpdateModel() {
|
||||
vRotateAngles.z += s;
|
||||
anim = true;
|
||||
}
|
||||
while (vRotateAngles.x >= 360)
|
||||
vRotateAngles.x -= 360;
|
||||
while (vRotateAngles.x <= -360)
|
||||
vRotateAngles.x += 360;
|
||||
while (vRotateAngles.y >= 360)
|
||||
vRotateAngles.y -= 360;
|
||||
while (vRotateAngles.y <= -360)
|
||||
vRotateAngles.y += 360;
|
||||
while (vRotateAngles.z >= 360)
|
||||
vRotateAngles.z -= 360;
|
||||
while (vRotateAngles.z <= -360)
|
||||
vRotateAngles.z += 360;
|
||||
if (vRotateAngles.x == 0.0)
|
||||
if (vRotateAngles.y == 0.0)
|
||||
if (vRotateAngles.z == 0.0)
|
||||
iAnim &= ~1; // kąty są zerowe
|
||||
// HACK: negative speed allows to work around legacy behaviour, where desired angle > 360 meant permanent rotation
|
||||
if( fRotateSpeed > 0.0 ) {
|
||||
while( vRotateAngles.x >= 360 )
|
||||
vRotateAngles.x -= 360;
|
||||
while( vRotateAngles.x <= -360 )
|
||||
vRotateAngles.x += 360;
|
||||
while( vRotateAngles.y >= 360 )
|
||||
vRotateAngles.y -= 360;
|
||||
while( vRotateAngles.y <= -360 )
|
||||
vRotateAngles.y += 360;
|
||||
while( vRotateAngles.z >= 360 )
|
||||
vRotateAngles.z -= 360;
|
||||
while( vRotateAngles.z <= -360 )
|
||||
vRotateAngles.z += 360;
|
||||
}
|
||||
|
||||
if( ( vRotateAngles.x == 0.0 )
|
||||
&& ( vRotateAngles.y == 0.0 )
|
||||
&& ( vRotateAngles.z == 0.0 ) ) {
|
||||
iAnim &= ~1; // kąty są zerowe
|
||||
}
|
||||
if (!anim)
|
||||
{ // nie potrzeba przeliczać już
|
||||
fRotateSpeed = 0.0;
|
||||
|
||||
242
Driver.cpp
242
Driver.cpp
@@ -152,6 +152,7 @@ const double EasyAcceleration = 0.85; //[m/ss]
|
||||
const double HardAcceleration = 9.81;
|
||||
const double PrepareTime = 2.0; //[s] przebłyski świadomości przy odpalaniu
|
||||
bool WriteLogFlag = false;
|
||||
double const deltalog = 0.05; // przyrost czasu
|
||||
|
||||
std::string StopReasonTable[] = {
|
||||
// przyczyny zatrzymania ruchu AI
|
||||
@@ -833,7 +834,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
double v; // prędkość
|
||||
double d; // droga
|
||||
double d_to_next_sem = 10000.0; //ustaiwamy na pewno dalej niż widzi AI
|
||||
bool isatpassengerstop { false }; // true if the consist is within acceptable range of w4 post
|
||||
IsAtPassengerStop = false;
|
||||
TCommandType go = TCommandType::cm_Unknown;
|
||||
eSignNext = NULL;
|
||||
// te flagi są ustawiane tutaj, w razie potrzeby
|
||||
@@ -921,7 +922,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
sSpeedTable[i].iFlags = 0;
|
||||
}
|
||||
}
|
||||
isatpassengerstop = (
|
||||
IsAtPassengerStop = (
|
||||
( sSpeedTable[ i ].fDist <= passengerstopmaxdistance )
|
||||
// Ra 2F1I: odległość plus długość pociągu musi być mniejsza od długości
|
||||
// peronu, chyba że pociąg jest dłuższy, to wtedy minimalna.
|
||||
@@ -941,7 +942,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
if( mvOccupied->Vel > 0.3 ) {
|
||||
// jeśli jedzie (nie trzeba czekać, aż się drgania wytłumią - drzwi zamykane od 1.0) to będzie zatrzymanie
|
||||
sSpeedTable[ i ].fVelNext = 0;
|
||||
} else if( true == isatpassengerstop ) {
|
||||
} else if( true == IsAtPassengerStop ) {
|
||||
// jeśli się zatrzymał przy W4, albo stał w momencie zobaczenia W4
|
||||
if( !AIControllFlag ) {
|
||||
// w razie przełączenia na AI ma nie podciągać do W4, gdy użytkownik zatrzymał za daleko
|
||||
@@ -1032,7 +1033,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
// jeśli są dalsze stacje, czekamy do godziny odjazdu
|
||||
if (TrainParams->IsTimeToGo(simulation::Time.data().wHour, simulation::Time.data().wMinute)) {
|
||||
// z dalszą akcją czekamy do godziny odjazdu
|
||||
isatpassengerstop = false;
|
||||
IsAtPassengerStop = false;
|
||||
// przy jakim dystansie (stanie licznika) ma przesunąć na następny postój
|
||||
fLastStopExpDist = mvOccupied->DistCounter + 0.050 + 0.001 * fLength;
|
||||
TrainParams->StationIndexInc(); // przejście do następnej
|
||||
@@ -1373,7 +1374,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
// 2014-02: jeśli stoi, a ma do przejechania kawałek, to niech jedzie
|
||||
if( ( mvOccupied->Vel < 0.01 )
|
||||
&& ( true == TestFlag( sSpeedTable[ i ].iFlags, ( spEnabled | spEvent | spPassengerStopPoint ) ) )
|
||||
&& ( false == isatpassengerstop ) ) {
|
||||
&& ( false == IsAtPassengerStop ) ) {
|
||||
// ma podjechać bliżej - czy na pewno w tym miejscu taki warunek?
|
||||
a = ( ( d > passengerstopmaxdistance ) || ( ( iDrivigFlags & moveStopCloser ) != 0 ) ?
|
||||
fAcc :
|
||||
@@ -1454,7 +1455,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
}
|
||||
|
||||
//analiza spisanych z tabelki ograniczeń i nadpisanie aktualnego
|
||||
if( ( true == isatpassengerstop ) && ( mvOccupied->Vel < 0.01 ) ) {
|
||||
if( ( true == IsAtPassengerStop ) && ( mvOccupied->Vel < 0.01 ) ) {
|
||||
// if stopped at a valid passenger stop, hold there
|
||||
fVelDes = 0.0;
|
||||
}
|
||||
@@ -1622,6 +1623,11 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche,
|
||||
mvOccupied->TrainType == dt_EZT ? -0.55 :
|
||||
mvOccupied->TrainType == dt_DMU ? -0.45 :
|
||||
-0.2 );
|
||||
// HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors
|
||||
if( ( mvOccupied->TrainType == dt_EZT )
|
||||
&& ( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) ) {
|
||||
fAccThreshold += 0.10;
|
||||
}
|
||||
}
|
||||
// TrainParams=NewTrainParams;
|
||||
// if (TrainParams)
|
||||
@@ -1670,11 +1676,6 @@ void TController::CloseLog()
|
||||
if (WriteLogFlag)
|
||||
{
|
||||
LogFile.close();
|
||||
// if WriteLogFlag)
|
||||
// CloseFile(AILogFile);
|
||||
/* append(AIlogFile);
|
||||
writeln(AILogFile,ElapsedTime5:2,": QUIT");
|
||||
close(AILogFile); */
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1737,11 +1738,8 @@ void TController::Activation()
|
||||
mvOccupied->DirectionForward(); // kierunek na 0
|
||||
while (mvOccupied->ActiveDir > 0)
|
||||
mvOccupied->DirectionBackward();
|
||||
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
|
||||
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
|
||||
mvOccupied->DecLocalBrakeLevel(LocalBrakePosNo); // zwolnienie hamulca w opuszczanym pojeździe
|
||||
// mvOccupied->BrakeLevelSet((mvOccupied->BrakeHandle==FVel6)?4:-2); //odcięcie na
|
||||
// zaworze maszynisty, FVel6 po drugiej stronie nie luzuje
|
||||
@@ -1751,8 +1749,7 @@ void TController::Activation()
|
||||
mvOccupied->ActiveCab = mvOccupied->CabNo; // użytkownik moze zmienić ActiveCab wychodząc
|
||||
mvOccupied->CabDeactivisation(); // tak jest w Train.cpp
|
||||
// przejście AI na drugą stronę EN57, ET41 itp.
|
||||
while (TestFlag(d->MoverParameters->Couplers[iDirection < 0 ? 1 : 0].CouplingFlag,
|
||||
ctrain_controll))
|
||||
while (TestFlag(d->MoverParameters->Couplers[iDirection < 0 ? 1 : 0].CouplingFlag, ctrain_controll))
|
||||
{ // jeśli pojazd z przodu jest ukrotniony, to przechodzimy do niego
|
||||
d = iDirection * d->DirectionGet() < 0 ? d->Next() :
|
||||
d->Prev(); // przechodzimy do następnego członu
|
||||
@@ -1816,8 +1813,7 @@ void TController::AutoRewident()
|
||||
// · masa (jako suma) -> jest w (fMass)
|
||||
while (d)
|
||||
{ // klasyfikacja pojazdów wg BrakeDelays i mocy (licznik)
|
||||
if (d->MoverParameters->Power <
|
||||
1) // - lokomotywa - Power>1 - ale może być nieczynna na końcu...
|
||||
if (d->MoverParameters->Power < 1) // - lokomotywa - Power>1 - ale może być nieczynna na końcu...
|
||||
if (TestFlag(d->MoverParameters->BrakeDelays, bdelay_R))
|
||||
++r; // - wagon pospieszny - jest R
|
||||
else if (TestFlag(d->MoverParameters->BrakeDelays, bdelay_G))
|
||||
@@ -1951,7 +1947,13 @@ void TController::AutoRewident()
|
||||
0.25 );
|
||||
|
||||
if( mvOccupied->TrainType == dt_EZT ) {
|
||||
fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
|
||||
if( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) {
|
||||
// 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 ] );
|
||||
}
|
||||
else {
|
||||
fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
|
||||
}
|
||||
fBrakeReaction = 0.25;
|
||||
}
|
||||
else if( mvOccupied->TrainType == dt_DMU ) {
|
||||
@@ -2083,13 +2085,11 @@ bool TController::CheckVehicles(TOrders user)
|
||||
if (AIControllFlag) // jeśli prowadzi komputer
|
||||
p->RaLightsSet(0, 0); // gasimy światła
|
||||
if (p->MoverParameters->EnginePowerSource.SourceType == TPowerSource::CurrentCollector)
|
||||
{ // jeśli pojazd posiada pantograf, to przydzielamy mu maskę, którą będzie informował o
|
||||
// jeździe bezprądowej
|
||||
{ // jeśli pojazd posiada pantograf, to przydzielamy mu maskę, którą będzie informował o jeździe bezprądowej
|
||||
p->iOverheadMask = pantmask;
|
||||
pantmask = pantmask << 1; // przesunięcie bitów, max. 32 pojazdy z pantografami w składzie
|
||||
}
|
||||
d = p->DirectionSet(d ? 1 : -1); // zwraca położenie następnego (1=zgodny,0=odwrócony -
|
||||
// względem czoła składu)
|
||||
d = p->DirectionSet(d ? 1 : -1); // zwraca położenie następnego (1=zgodny,0=odwrócony - względem czoła składu)
|
||||
p->ctOwner = this; // dominator oznacza swoje terytorium
|
||||
p = p->Next(); // pojazd podłączony od tyłu (licząc od czoła)
|
||||
}
|
||||
@@ -2109,9 +2109,6 @@ bool TController::CheckVehicles(TOrders user)
|
||||
Lights(
|
||||
frontlights,
|
||||
rearlights );
|
||||
#if LOGPRESS == 0
|
||||
AutoRewident(); // nastawianie hamulca do jazdy pociągowej
|
||||
#endif
|
||||
}
|
||||
else if (OrderCurrentGet() & (Shunt | Connect))
|
||||
{
|
||||
@@ -2144,46 +2141,59 @@ bool TController::CheckVehicles(TOrders user)
|
||||
Lights( 0, light::headlight_right );
|
||||
}
|
||||
}
|
||||
// nastawianie hamulca do jazdy pociągowej
|
||||
if( OrderCurrentGet() & ( Obey_train | Shunt ) ) {
|
||||
AutoRewident();
|
||||
}
|
||||
}
|
||||
else // Ra 2014-02: lepiej tu niż w pętli obsługującej komendy, bo tam się zmieni informacja
|
||||
// o składzie
|
||||
switch (user) // gdy człowiek i gdy nastąpiło połącznie albo rozłączenie
|
||||
{
|
||||
case Change_direction:
|
||||
while (OrderCurrentGet() & (Change_direction))
|
||||
JumpToNextOrder(); // zmianę kierunku też można olać, ale zmienić kierunek
|
||||
// skanowania!
|
||||
else { // gdy człowiek i gdy nastąpiło połącznie albo rozłączenie
|
||||
// Ra 2014-02: lepiej tu niż w pętli obsługującej komendy, bo tam się zmieni informacja o składzie
|
||||
switch (user) {
|
||||
case Change_direction: {
|
||||
while (OrderCurrentGet() & (Change_direction)) {
|
||||
// zmianę kierunku też można olać, ale zmienić kierunek skanowania!
|
||||
JumpToNextOrder();
|
||||
}
|
||||
break;
|
||||
case Connect:
|
||||
while (OrderCurrentGet() & (Change_direction))
|
||||
JumpToNextOrder(); // zmianę kierunku też można olać, ale zmienić kierunek
|
||||
// skanowania!
|
||||
if (OrderCurrentGet() & (Connect))
|
||||
{ // jeśli miało być łączenie, zakładamy, że jest dobrze (sprawdzić?)
|
||||
}
|
||||
case Connect: {
|
||||
while (OrderCurrentGet() & (Change_direction)) {
|
||||
// zmianę kierunku też można olać, ale zmienić kierunek skanowania!
|
||||
JumpToNextOrder();
|
||||
}
|
||||
if (OrderCurrentGet() & (Connect)) {
|
||||
// jeśli miało być łączenie, zakładamy, że jest dobrze (sprawdzić?)
|
||||
iCoupler = 0; // koniec z doczepianiem
|
||||
iDrivigFlags &= ~moveConnect; // zdjęcie flagi doczepiania
|
||||
JumpToNextOrder(); // wykonanie następnej komendy
|
||||
if (OrderCurrentGet() & (Change_direction))
|
||||
JumpToNextOrder(); // zmianę kierunku też można olać, ale zmienić kierunek
|
||||
// skanowania!
|
||||
if (OrderCurrentGet() & (Change_direction)) {
|
||||
// zmianę kierunku też można olać, ale zmienić kierunek skanowania!
|
||||
JumpToNextOrder();
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case Disconnect:
|
||||
while (OrderCurrentGet() & (Change_direction))
|
||||
JumpToNextOrder(); // zmianę kierunku też można olać, ale zmienić kierunek
|
||||
// skanowania!
|
||||
if (OrderCurrentGet() & (Disconnect))
|
||||
{ // wypadało by sprawdzić, czy odczepiono wagony w odpowiednim miejscu
|
||||
// (iVehicleCount)
|
||||
JumpToNextOrder(); // wykonanie następnej komendy
|
||||
if (OrderCurrentGet() & (Change_direction))
|
||||
JumpToNextOrder(); // zmianę kierunku też można olać, ale zmienić kierunek
|
||||
// skanowania!
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case Disconnect: {
|
||||
while (OrderCurrentGet() & (Change_direction)) {
|
||||
// zmianę kierunku też można olać, ale zmienić kierunek skanowania!
|
||||
JumpToNextOrder();
|
||||
}
|
||||
if (OrderCurrentGet() & (Disconnect)) {
|
||||
// wypadało by sprawdzić, czy odczepiono wagony w odpowiednim miejscu (iVehicleCount)
|
||||
JumpToNextOrder(); // wykonanie następnej komendy
|
||||
if (OrderCurrentGet() & (Change_direction)) {
|
||||
// zmianę kierunku też można olać, ale zmienić kierunek skanowania!
|
||||
JumpToNextOrder();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
}
|
||||
// Ra 2014-09: tymczasowo prymitywne ustawienie warunku pod kątem SN61
|
||||
if( ( mvOccupied->TrainType == dt_EZT )
|
||||
|| ( mvOccupied->TrainType == dt_DMU )
|
||||
@@ -2428,7 +2438,7 @@ bool TController::PrepareEngine()
|
||||
; // zerowanie napędu
|
||||
mvControlling->ConvOvldFlag = false; // reset nadmiarowego
|
||||
}
|
||||
else if (false == mvControlling->Mains) {
|
||||
else if (false == IsLineBreakerClosed) {
|
||||
while (DecSpeed(true))
|
||||
; // zerowanie napędu
|
||||
if( mvOccupied->TrainType == dt_SN61 ) {
|
||||
@@ -2441,24 +2451,6 @@ bool TController::PrepareEngine()
|
||||
|| ( std::max( mvControlling->GetTrainsetVoltage(), std::abs( mvControlling->RunningTraction.TractionVoltage ) ) > mvControlling->EnginePowerSource.CollectorParameters.MinV ) ) {
|
||||
mvControlling->MainSwitch( true );
|
||||
}
|
||||
/*
|
||||
if (mvControlling->EngineType == DieselEngine) {
|
||||
// Ra 2014-06: dla SN61 trzeba wrzucić pierwszą pozycję - nie wiem, czy tutaj...
|
||||
// kiedyś działało...
|
||||
if (!mvControlling->MainCtrlPos) {
|
||||
if( mvControlling->RList[ 0 ].R == 0.0 ) {
|
||||
// gdy na pozycji 0 dawka paliwa jest zerowa, to zgaśnie dlatego trzeba zwiększyć pozycję
|
||||
mvControlling->IncMainCtrl( 1 );
|
||||
}
|
||||
if( ( !mvControlling->ScndCtrlPos ) // jeśli bieg nie został ustawiony
|
||||
&& ( !mvControlling->MotorParam[ 0 ].AutoSwitch ) // gdy biegi ręczne
|
||||
&& ( mvControlling->MotorParam[ 0 ].mIsat == 0.0 ) ) { // bl,mIsat,fi,mfi
|
||||
// pierwszy bieg
|
||||
mvControlling->IncScndCtrl( 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
else {
|
||||
OK = ( OrderDirectionChange( iDirection, mvOccupied ) == -1 );
|
||||
@@ -2860,7 +2852,7 @@ bool TController::IncSpeed()
|
||||
auto const sufficienttractionforce { std::abs( mvControlling->Ft ) > ( IsHeavyCargoTrain ? 125 : 100 ) * 1000.0 };
|
||||
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 useseriesmodevoltage { 0.80 * mvControlling->EnginePowerSource.CollectorParameters.MaxV };
|
||||
auto const useseriesmodevoltage { mvControlling->EnginePowerSource.CollectorParameters.MaxV * ( IsHeavyCargoTrain ? 0.70 : 0.80 ) };
|
||||
auto const useseriesmode = (
|
||||
( mvControlling->Imax > mvControlling->ImaxLo )
|
||||
|| ( fVoltage < useseriesmodevoltage )
|
||||
@@ -3204,8 +3196,8 @@ void TController::SpeedCntrl(double DesiredSpeed)
|
||||
else if (mvControlling->ScndCtrlPosNo > 1)
|
||||
{
|
||||
int DesiredPos = 1 + mvControlling->ScndCtrlPosNo * ((DesiredSpeed - 1.0) / mvControlling->Vmax);
|
||||
while (mvControlling->ScndCtrlPos > DesiredPos) mvControlling->DecScndCtrl(1);
|
||||
while (mvControlling->ScndCtrlPos < DesiredPos) mvControlling->IncScndCtrl(1);
|
||||
while( ( mvControlling->ScndCtrlPos > DesiredPos ) && ( true == mvControlling->DecScndCtrl( 1 ) ) ) { ; } // all work is done in the condition loop
|
||||
while( ( mvControlling->ScndCtrlPos < DesiredPos ) && ( true == mvControlling->IncScndCtrl( 1 ) ) ) { ; } // all work is done in the condition loop
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3827,36 +3819,58 @@ TController::UpdateSituation(double dt) {
|
||||
TDynamicObject *p = pVehicles[0]; // pojazd na czole składu
|
||||
while (p)
|
||||
{ // sprawdzenie odhamowania wszystkich połączonych pojazdów
|
||||
auto *vehicle { p->MoverParameters };
|
||||
if (Ready) {
|
||||
// bo jak coś nie odhamowane, to dalej nie ma co sprawdzać
|
||||
if (p->MoverParameters->BrakePress >= 0.4) // wg UIC określone sztywno na 0.04
|
||||
if (vehicle->BrakePress >= 0.4) // wg UIC określone sztywno na 0.04
|
||||
{
|
||||
Ready = false; // nie gotowy
|
||||
// Ra: odluźnianie przeładowanych lokomotyw, ciągniętych na zimno - prowizorka...
|
||||
if (AIControllFlag) // skład jak dotąd był wyluzowany
|
||||
{
|
||||
if( ( mvOccupied->BrakeCtrlPos == 0 ) // jest pozycja jazdy
|
||||
&& ( ( p->MoverParameters->Hamulec->GetBrakeStatus() & b_dmg ) == 0 ) // brake isn't broken
|
||||
&& ( p->MoverParameters->PipePress - 5.0 > -0.1 ) // jeśli ciśnienie jak dla jazdy
|
||||
&& ( p->MoverParameters->Hamulec->GetCRP() > p->MoverParameters->PipePress + 0.12 ) ) { // za dużo w zbiorniku
|
||||
&& ( ( vehicle->Hamulec->GetBrakeStatus() & b_dmg ) == 0 ) // brake isn't broken
|
||||
&& ( vehicle->PipePress - 5.0 > -0.1 ) // jeśli ciśnienie jak dla jazdy
|
||||
&& ( vehicle->Hamulec->GetCRP() > vehicle->PipePress + 0.12 ) ) { // za dużo w zbiorniku
|
||||
// indywidualne luzowanko
|
||||
p->MoverParameters->BrakeReleaser( 1 );
|
||||
vehicle->BrakeReleaser( 1 );
|
||||
}
|
||||
if (p->MoverParameters->Power > 0.01) // jeśli ma silnik
|
||||
if (p->MoverParameters->FuseFlag) // wywalony nadmiarowy
|
||||
Need_TryAgain = true; // reset jak przy wywaleniu nadmiarowego
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fReady < p->MoverParameters->BrakePress)
|
||||
fReady = p->MoverParameters->BrakePress; // szukanie najbardziej zahamowanego
|
||||
if (fReady < vehicle->BrakePress)
|
||||
fReady = vehicle->BrakePress; // szukanie najbardziej zahamowanego
|
||||
if( ( dy = p->VectorFront().y ) != 0.0 ) {
|
||||
// istotne tylko dla pojazdów na pochyleniu
|
||||
// ciężar razy składowa styczna grawitacji
|
||||
fAccGravity -= p->MoverParameters->TotalMassxg * dy * ( p->DirectionGet() == iDirection ? 1 : -1 );
|
||||
fAccGravity -= vehicle->TotalMassxg * dy * ( p->DirectionGet() == iDirection ? 1 : -1 );
|
||||
}
|
||||
if( ( vehicle->Power > 0.01 ) // jeśli ma silnik
|
||||
&& ( vehicle->FuseFlag ) ) { // wywalony nadmiarowy
|
||||
Need_TryAgain = true; // reset jak przy wywaleniu nadmiarowego
|
||||
}
|
||||
p = p->Next(); // pojazd podłączony z tyłu (patrząc od czoła)
|
||||
}
|
||||
|
||||
// test state of main switch in all powered vehicles under control
|
||||
IsLineBreakerClosed = ( mvOccupied->Power > 0.01 ? mvOccupied->Mains : true );
|
||||
p = pVehicle;
|
||||
while( ( true == IsLineBreakerClosed )
|
||||
&& ( ( p = p->PrevC( coupling::control) ) != nullptr ) ) {
|
||||
auto const *vehicle { p->MoverParameters };
|
||||
if( vehicle->Power > 0.01 ) {
|
||||
IsLineBreakerClosed = ( IsLineBreakerClosed && vehicle->Mains );
|
||||
}
|
||||
}
|
||||
p = pVehicle;
|
||||
while( ( true == IsLineBreakerClosed )
|
||||
&& ( ( p = p->NextC( coupling::control ) ) != nullptr ) ) {
|
||||
auto const *vehicle { p->MoverParameters };
|
||||
if( vehicle->Power > 0.01 ) {
|
||||
IsLineBreakerClosed = ( IsLineBreakerClosed && vehicle->Mains );
|
||||
}
|
||||
}
|
||||
|
||||
if( iDirection ) {
|
||||
// siłę generują pojazdy na pochyleniu ale działa ona całość składu, więc a=F/m
|
||||
fAccGravity *= iDirection;
|
||||
@@ -4087,6 +4101,12 @@ TController::UpdateSituation(double dt) {
|
||||
// dla nastawienia G koniecznie należy wydłużyć drogę na czas reakcji
|
||||
fBrakeDist += 2 * mvOccupied->Vel;
|
||||
}
|
||||
if( ( mvOccupied->Vel > 0.05 )
|
||||
&& ( mvControlling->EngineType == TEngineType::ElectricInductionMotor )
|
||||
&& ( ( mvControlling->TrainType & dt_EZT ) != 0 ) ) {
|
||||
// HACK: make the induction motor powered EMUs start braking slightly earlier
|
||||
fBrakeDist += 10.0;
|
||||
}
|
||||
/*
|
||||
// take into account effect of gravity (but to stay on safe side of calculations, only downhill)
|
||||
if( fAccGravity > 0.025 ) {
|
||||
@@ -4743,8 +4763,8 @@ TController::UpdateSituation(double dt) {
|
||||
fMinProximityDist : // cars can bunch up tighter
|
||||
fMaxProximityDist ) ); // other vehicle types less so
|
||||
*/
|
||||
double k = coupler->Connected->Vel; // prędkość pojazdu z przodu (zakładając,
|
||||
// że jedzie w tę samą stronę!!!)
|
||||
// prędkość pojazdu z przodu (zakładając, że jedzie w tę samą stronę!!!)
|
||||
double k = coupler->Connected->Vel;
|
||||
if( k - vel < 5 ) {
|
||||
// porównanie modułów prędkości [km/h]
|
||||
// zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej
|
||||
@@ -4752,6 +4772,26 @@ TController::UpdateSituation(double dt) {
|
||||
ActualProximityDist,
|
||||
vehicle->fTrackBlock );
|
||||
|
||||
if( ActualProximityDist <= (
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
100.0 : // cars
|
||||
250.0 ) ) { // others
|
||||
// regardless of driving mode at close distance take precaution measures:
|
||||
// match the other vehicle's speed or slow down if the other vehicle is stopped
|
||||
VelDesired =
|
||||
min_speed(
|
||||
VelDesired,
|
||||
std::max(
|
||||
k,
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
40.0 : // cars
|
||||
20.0 ) ); // others
|
||||
if( vel > VelDesired + fVelPlus ) {
|
||||
// if going too fast force some prompt braking
|
||||
AccPreferred = std::min( -0.65, AccPreferred );
|
||||
}
|
||||
}
|
||||
|
||||
double const distance = vehicle->fTrackBlock - fMaxProximityDist - ( fBrakeDist * 1.15 ); // odległość bezpieczna zależy od prędkości
|
||||
if( distance < 0.0 ) {
|
||||
// jeśli odległość jest zbyt mała
|
||||
@@ -4801,7 +4841,7 @@ TController::UpdateSituation(double dt) {
|
||||
}
|
||||
}
|
||||
ReactionTime = (
|
||||
vel != 0.0 ?
|
||||
mvOccupied->Vel > 0.01 ?
|
||||
0.1 : // orientuj się, bo jest goraco
|
||||
2.0 ); // we're already standing still, so take it easy
|
||||
}
|
||||
@@ -5219,10 +5259,10 @@ TController::UpdateSituation(double dt) {
|
||||
return; // ...and don't touch any other controls
|
||||
}
|
||||
|
||||
if (mvControlling->ConvOvldFlag ||
|
||||
!mvControlling->Mains) // WS może wywalić z powodu błędu w drutach
|
||||
{ // wywalił bezpiecznik nadmiarowy przetwornicy
|
||||
PrepareEngine(); // próba ponownego załączenia
|
||||
if( ( true == mvControlling->ConvOvldFlag ) // wywalił bezpiecznik nadmiarowy przetwornicy
|
||||
|| ( false == IsLineBreakerClosed ) ) { // WS może wywalić z powodu błędu w drutach
|
||||
// próba ponownego załączenia
|
||||
PrepareEngine();
|
||||
}
|
||||
// włączanie bezpiecznika
|
||||
if ((mvControlling->EngineType == TEngineType::ElectricSeriesMotor) ||
|
||||
@@ -5784,7 +5824,7 @@ void TController::OrdersInit(double fVel)
|
||||
// Ale mozna by je zapodac ze scenerii
|
||||
};
|
||||
|
||||
std::string TController::StopReasonText()
|
||||
std::string TController::StopReasonText() const
|
||||
{ // informacja tekstowa o przyczynie zatrzymania
|
||||
if (eStopReason != 7) // zawalidroga będzie inaczej
|
||||
return StopReasonTable[eStopReason];
|
||||
|
||||
376
Driver.h
376
Driver.h
@@ -129,12 +129,7 @@ class TSpeedPos
|
||||
double fDist{ 0.0 }; // aktualna odległość (ujemna gdy minięte)
|
||||
double fVelNext{ -1.0 }; // prędkość obowiązująca od tego miejsca
|
||||
double fSectionVelocityDist{ 0.0 }; // długość ograniczenia prędkości
|
||||
// double fAcc;
|
||||
int iFlags{ spNone }; // flagi typu wpisu do tabelki
|
||||
// 1=istotny,2=tor,4=odwrotnie,8-zwrotnica (może się zmienić),16-stan
|
||||
// zwrotnicy,32-minięty,64=koniec,128=łuk
|
||||
// 0x100=event,0x200=manewrowa,0x400=przystanek,0x800=SBL,0x1000=wysłana komenda,0x2000=W5
|
||||
// 0x4000=semafor,0x10000=zatkanie
|
||||
bool bMoved{ false }; // czy przesunięty (dotyczy punktu zatrzymania w peronie)
|
||||
Math3D::vector3 vPos; // współrzędne XYZ do liczenia odległości
|
||||
struct
|
||||
@@ -174,88 +169,76 @@ static const int BrakeAccTableSize = 20;
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class TController {
|
||||
// TBD: few authorized inspectors, or bunch of public getters?
|
||||
friend class TTrain;
|
||||
friend class drivingaid_panel;
|
||||
friend class timetable_panel;
|
||||
friend class debug_panel;
|
||||
friend class whois_event;
|
||||
|
||||
private: // obsługa tabelki prędkości (musi mieć możliwość odhaczania stacji w rozkładzie)
|
||||
int iLast{ 0 }; // ostatnia wypełniona pozycja w tabeli <iFirst (modulo iSpeedTableSize)
|
||||
int iTableDirection{ 0 }; // kierunek zapełnienia tabelki względem pojazdu z AI
|
||||
std::vector<TSpeedPos> sSpeedTable;
|
||||
double fLastVel = 0.0; // prędkość na poprzednio sprawdzonym torze
|
||||
TTrack *tLast = nullptr; // ostatni analizowany tor
|
||||
basic_event *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu
|
||||
std::size_t SemNextIndex{ std::size_t(-1) };
|
||||
std::size_t SemNextStopIndex{ std::size_t( -1 ) };
|
||||
double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki
|
||||
// parametry aktualnego składu
|
||||
double fLength = 0.0; // długość składu (do wyciągania z ograniczeń)
|
||||
double fMass = 0.0; // całkowita masa do liczenia stycznej składowej grawitacji
|
||||
public:
|
||||
double fAccGravity = 0.0; // przyspieszenie składowej stycznej grawitacji
|
||||
basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2]
|
||||
std::string asNextStop; // nazwa następnego punktu zatrzymania wg rozkładu
|
||||
int iStationStart = 0; // numer pierwszej stacji pokazywanej na podglądzie rozkładu
|
||||
// parametry sterowania pojazdem (stan, hamowanie)
|
||||
private:
|
||||
double fShuntVelocity = 40.0; // maksymalna prędkość manewrowania, zależy m.in. od składu // domyślna prędkość manewrowa
|
||||
int iVehicles = 0; // ilość pojazdów w składzie
|
||||
int iEngineActive = 0; // ABu: Czy silnik byl juz zalaczony; Ra: postęp w załączaniu
|
||||
bool Psyche = false;
|
||||
int iDrivigFlags = // flagi bitowe ruchu
|
||||
moveStopPoint | // podjedź do W4 możliwie blisko
|
||||
moveStopHere | // nie podjeżdżaj do semafora, jeśli droga nie jest wolna
|
||||
moveStartHorn; // podaj sygnał po podaniu wolnej drogi
|
||||
double fDriverBraking = 0.0; // po pomnożeniu przez v^2 [km/h] daje ~drogę hamowania [m]
|
||||
double fDriverDist = 0.0; // dopuszczalna odległość podjechania do przeszkody
|
||||
double fVelMax = -1.0; // maksymalna prędkość składu (sprawdzany każdy pojazd)
|
||||
public:
|
||||
double fBrakeDist = 0.0; // przybliżona droga hamowania
|
||||
double BrakeAccFactor() const;
|
||||
double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h)
|
||||
double fNominalAccThreshold = 0.0; // nominalny próg opóźnienia dla zadziałania hamulca
|
||||
double fAccThreshold = 0.0; // aktualny próg opóźnienia dla zadziałania hamulca
|
||||
double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca
|
||||
// dla fBrake_aX:
|
||||
// indeks [0] - wartości odpowiednie dla aktualnej prędkości
|
||||
// a potem jest 20 wartości dla różnych prędkości zmieniających się co 5 % Vmax pojazdu obsadzonego
|
||||
double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // opóźnienia hamowania przy ustawieniu zaworu maszynisty w pozycji 1.0
|
||||
double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // przyrost opóźnienia hamowania po przestawieniu zaworu maszynisty o 0,25 pozycji
|
||||
double BrakingInitialLevel{ 1.0 };
|
||||
double BrakingLevelIncrease{ 0.25 };
|
||||
bool IsCargoTrain{ false };
|
||||
bool IsHeavyCargoTrain{ false };
|
||||
double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku
|
||||
double 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 BrakeChargingCooldown {}; // prevents the ai from trying to charge the train brake too frequently
|
||||
double fReady = 0.0; // poziom odhamowania wagonów
|
||||
bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow
|
||||
private:
|
||||
double LastUpdatedTime = 0.0; // czas od ostatniego logu
|
||||
double ElapsedTime = 0.0; // czas od poczatku logu
|
||||
double deltalog = 0.05; // przyrost czasu
|
||||
double LastReactionTime = 0.0;
|
||||
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
|
||||
TAction eAction { TAction::actUnknown }; // aktualny stan
|
||||
public:
|
||||
TController( bool AI, TDynamicObject *NewControll, bool InitPsyche, bool primary = true );
|
||||
~TController();
|
||||
|
||||
// ai operations logic
|
||||
// methods
|
||||
public:
|
||||
void UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę
|
||||
void MoveTo(TDynamicObject *to);
|
||||
void TakeControl(bool yes);
|
||||
inline
|
||||
bool Primary() const {
|
||||
return ( ( iDrivigFlags & movePrimary ) != 0 ); };
|
||||
inline
|
||||
TMoverParameters const *Controlling() const {
|
||||
return mvControlling; }
|
||||
void DirectionInitial();
|
||||
inline
|
||||
int Direction() const {
|
||||
return iDirection; }
|
||||
inline
|
||||
TAction GetAction() {
|
||||
return eAction; }
|
||||
private:
|
||||
void Activation(); // umieszczenie obsady w odpowiednim członie
|
||||
void ControllingSet(); // znajduje człon do sterowania
|
||||
void SetDriverPsyche();
|
||||
bool IncBrake();
|
||||
bool DecBrake();
|
||||
bool IncSpeed();
|
||||
bool DecSpeed(bool force = false);
|
||||
void SpeedSet();
|
||||
void SpeedCntrl(double DesiredSpeed);
|
||||
double ESMVelocity(bool Main);
|
||||
bool UpdateHeating();
|
||||
// uaktualnia informacje o prędkości
|
||||
void SetVelocity(double NewVel, double NewVelNext, TStopReason r = stopNone);
|
||||
int CheckDirection();
|
||||
void WaitingSet(double Seconds);
|
||||
void DirectionForward(bool forward);
|
||||
int OrderDirectionChange(int newdir, TMoverParameters *Vehicle);
|
||||
void Lights(int head, int rear);
|
||||
std::string StopReasonText() const;
|
||||
double BrakeAccFactor() const;
|
||||
// modifies brake distance for low target speeds, to ease braking rate in such situations
|
||||
float
|
||||
braking_distance_multiplier( float const Targetvelocity ) const;
|
||||
inline
|
||||
int DrivigFlags() const {
|
||||
return iDrivigFlags; };
|
||||
// members
|
||||
public:
|
||||
bool AIControllFlag = false; // rzeczywisty/wirtualny maszynista
|
||||
/*
|
||||
int iRouteWanted = 3; // oczekiwany kierunek jazdy (0-stop,1-lewo,2-prawo,3-prosto) np. odpala migacz lub czeka na stan zwrotnicy
|
||||
*/
|
||||
private:
|
||||
int iOverheadZero = 0; // suma bitowa jezdy bezprądowej, bity ustawiane przez pojazdy z podniesionymi pantografami
|
||||
int iOverheadDown = 0; // suma bitowa opuszczenia pantografów, bity ustawiane przez pojazdy z podniesionymi pantografami
|
||||
private:
|
||||
bool Psyche = false;
|
||||
int HelperState = 0; //stan pomocnika maszynisty
|
||||
TDynamicObject *pVehicle = nullptr; // pojazd w którym siedzi sterujący
|
||||
TDynamicObject *pVehicles[2]; // skrajne pojazdy w składzie (niekoniecznie bezpośrednio sterowane)
|
||||
TMoverParameters *mvControlling = nullptr; // jakim pojazdem steruje (może silnikowym w EZT)
|
||||
TMoverParameters *mvOccupied = nullptr; // jakim pojazdem hamuje
|
||||
Mtable::TTrainParameters *TrainParams = nullptr; // rozkład jazdy zawsze jest, nawet jeśli pusty
|
||||
int iRadioChannel = 1; // numer aktualnego kanału radiowego
|
||||
int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia)
|
||||
sound_source tsGuardSignal { sound_placement::internal };
|
||||
std::string VehicleName;
|
||||
std::array<int, 2> m_lighthints { -1 }; // suggested light patterns
|
||||
public:
|
||||
int HelperState = 0; //stan pomocnika maszynisty
|
||||
double AccPreferred = 0.0; // preferowane przyspieszenie (wg psychiki kierującego, zmniejszana przy wykryciu kolizji)
|
||||
double AccDesired = AccPreferred; // przyspieszenie, jakie ma utrzymywać (<0:nie przyspieszaj,<-0.1:hamuj)
|
||||
double VelDesired = 0.0; // predkość, z jaką ma jechać, wynikająca z analizy tableki; <=VelSignal
|
||||
@@ -269,18 +252,8 @@ private:
|
||||
double VelRoad = -1.0; // aktualna prędkość drogowa (ze znaku W27) (PutValues albo komendą) // prędkość drogowa bez ograniczenia
|
||||
double VelNext = 120.0; // prędkość, jaka ma być po przejechaniu długości ProximityDist
|
||||
double VelRestricted = -1.0; // speed of travel after passing a permissive signal at stop
|
||||
private:
|
||||
double FirstSemaphorDist = 10000.0; // odległość do pierwszego znalezionego semafora
|
||||
public:
|
||||
double ActualProximityDist = 1.0; // odległość brana pod uwagę przy wyliczaniu prędkości i przyspieszenia
|
||||
private:
|
||||
Math3D::vector3 vCommandLocation; // polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego
|
||||
// odnosi sie komenda
|
||||
TOrders OrderList[maxorders]; // lista rozkazów
|
||||
int OrderPos = 0,
|
||||
OrderTop = 0; // rozkaz aktualny oraz wolne miejsce do wstawiania nowych
|
||||
std::ofstream LogFile; // zapis parametrow fizycznych
|
||||
std::ofstream AILogFile; // log AI
|
||||
int iDirection = 0; // kierunek jazdy względem sprzęgów pojazdu, w którym siedzi AI (1=przód,-1=tył)
|
||||
int iDirectionOrder = 0; //żadany kierunek jazdy (służy do zmiany kierunku)
|
||||
int iVehicleCount = -2; // wartość neutralna // ilość pojazdów do odłączenia albo zabrania ze składu (-1=wszystkie)
|
||||
@@ -288,146 +261,187 @@ private:
|
||||
int iDriverFailCount = 0; // licznik błędów AI
|
||||
bool Need_TryAgain = false; // true, jeśli druga pozycja w elektryku nie załapała
|
||||
bool Need_BrakeRelease = true;
|
||||
|
||||
public:
|
||||
bool IsAtPassengerStop{ false }; // true if the consist is within acceptable range of w4 post
|
||||
double fMinProximityDist = 30.0; // stawanie między 30 a 60 m przed przeszkodą // minimalna oległość do przeszkody, jaką należy zachować
|
||||
double fOverhead1 = 3000.0; // informacja o napięciu w sieci trakcyjnej (0=brak drutu, zatrzymaj!)
|
||||
double fOverhead2 = -1.0; // informacja o sposobie jazdy (-1=normalnie, 0=bez prądu, >0=z opuszczonym i ograniczeniem prędkości)
|
||||
int iOverheadZero = 0; // suma bitowa jezdy bezprądowej, bity ustawiane przez pojazdy z podniesionymi pantografami
|
||||
int iOverheadDown = 0; // suma bitowa opuszczenia pantografów, bity ustawiane przez pojazdy z podniesionymi pantografami
|
||||
double fVoltage = 0.0; // uśrednione napięcie sieci: przy spadku poniżej wartości minimalnej opóźnić rozruch o losowy czas
|
||||
private:
|
||||
double fMaxProximityDist = 50.0; // stawanie między 30 a 60 m przed przeszkodą // akceptowalna odległość stanięcia przed przeszkodą
|
||||
TStopReason eStopReason = stopSleep; // powód zatrzymania przy ustawieniu zerowej prędkości // na początku śpi
|
||||
std::string VehicleName;
|
||||
double fVelPlus = 0.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania
|
||||
double fVelMinus = 0.0; // margines obniżenia prędkości, powodujący załączenie napędu
|
||||
double fWarningDuration = 0.0; // ile czasu jeszcze trąbić
|
||||
double WaitingTime = 0.0; // zliczany czas oczekiwania do samoistnego ruszenia
|
||||
double WaitingExpireTime = 31.0; // tyle ma czekać, zanim się ruszy // maksymlany czas oczekiwania do samoistnego ruszenia
|
||||
double IdleTime {}; // keeps track of time spent at a stop
|
||||
public:
|
||||
double fStopTime = 0.0; // czas postoju przed dalszą jazdą (np. na przystanku)
|
||||
double fShuntVelocity = 40.0; // maksymalna prędkość manewrowania, zależy m.in. od składu // domyślna prędkość manewrowa
|
||||
int iDrivigFlags = // flagi bitowe ruchu
|
||||
moveStopPoint | // podjedź do W4 możliwie blisko
|
||||
moveStopHere | // nie podjeżdżaj do semafora, jeśli droga nie jest wolna
|
||||
moveStartHorn; // podaj sygnał po podaniu wolnej drogi
|
||||
double fDriverBraking = 0.0; // po pomnożeniu przez v^2 [km/h] daje ~drogę hamowania [m]
|
||||
double fDriverDist = 0.0; // dopuszczalna odległość podjechania do przeszkody
|
||||
double fVelMax = -1.0; // maksymalna prędkość składu (sprawdzany każdy pojazd)
|
||||
double fBrakeDist = 0.0; // przybliżona droga hamowania
|
||||
double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h)
|
||||
double fNominalAccThreshold = 0.0; // nominalny próg opóźnienia dla zadziałania hamulca
|
||||
double fAccThreshold = 0.0; // aktualny próg opóźnienia dla zadziałania hamulca
|
||||
double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca
|
||||
// dla fBrake_aX:
|
||||
// indeks [0] - wartości odpowiednie dla aktualnej prędkości
|
||||
// a potem jest 20 wartości dla różnych prędkości zmieniających się co 5 % Vmax pojazdu obsadzonego
|
||||
double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // opóźnienia hamowania przy ustawieniu zaworu maszynisty w pozycji 1.0
|
||||
double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // przyrost opóźnienia hamowania po przestawieniu zaworu maszynisty o 0,25 pozycji
|
||||
double BrakingInitialLevel{ 1.0 };
|
||||
double BrakingLevelIncrease{ 0.25 };
|
||||
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 BrakeChargingCooldown {}; // prevents the ai from trying to charge the train brake too frequently
|
||||
double LastReactionTime = 0.0;
|
||||
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
|
||||
TAction eAction { TAction::actUnknown }; // aktualny stan
|
||||
|
||||
private: //---//---//---//---// koniec zmiennych, poniżej metody //---//---//---//---//
|
||||
void SetDriverPsyche();
|
||||
bool PrepareEngine();
|
||||
bool ReleaseEngine();
|
||||
bool IncBrake();
|
||||
bool DecBrake();
|
||||
bool IncSpeed();
|
||||
bool DecSpeed(bool force = false);
|
||||
void SpeedSet();
|
||||
void SpeedCntrl(double DesiredSpeed);
|
||||
void Doors(bool const Open, int const Side = 0);
|
||||
// returns true if any vehicle in the consist has an open door
|
||||
bool doors_open() const;
|
||||
void RecognizeCommand(); // odczytuje komende przekazana lokomotywie
|
||||
void Activation(); // umieszczenie obsady w odpowiednim członie
|
||||
void ControllingSet(); // znajduje człon do sterowania
|
||||
void AutoRewident(); // ustawia hamulce w składzie
|
||||
double ESMVelocity(bool Main);
|
||||
public:
|
||||
// orders
|
||||
// methods
|
||||
public:
|
||||
void PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation, TStopReason reason = stopComm);
|
||||
bool PutCommand( std::string NewCommand, double NewValue1, double NewValue2, glm::dvec3 const *NewLocation, TStopReason reason = stopComm );
|
||||
void UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę
|
||||
bool UpdateHeating();
|
||||
// procedury dotyczace rozkazow dla maszynisty
|
||||
// uaktualnia informacje o prędkości
|
||||
void SetVelocity(double NewVel, double NewVelNext, TStopReason r = stopNone);
|
||||
public:
|
||||
private:
|
||||
void RecognizeCommand(); // odczytuje komende przekazana lokomotywie
|
||||
void JumpToNextOrder();
|
||||
void JumpToFirstOrder();
|
||||
void OrderPush(TOrders NewOrder);
|
||||
void OrderNext(TOrders NewOrder);
|
||||
inline TOrders OrderCurrentGet();
|
||||
inline TOrders OrderNextGet();
|
||||
bool CheckVehicles(TOrders user = Wait_for_orders);
|
||||
int CheckDirection();
|
||||
|
||||
private:
|
||||
void CloseLog();
|
||||
void OrderCheck();
|
||||
|
||||
public:
|
||||
void OrdersInit(double fVel);
|
||||
void OrdersClear();
|
||||
void OrdersDump();
|
||||
TController( bool AI, TDynamicObject *NewControll, bool InitPsyche, bool primary = true );
|
||||
std::string OrderCurrent() const;
|
||||
void WaitingSet(double Seconds);
|
||||
|
||||
private:
|
||||
std::string Order2Str(TOrders Order) const;
|
||||
void DirectionForward(bool forward);
|
||||
int OrderDirectionChange(int newdir, TMoverParameters *Vehicle);
|
||||
void Lights(int head, int rear);
|
||||
// members
|
||||
Math3D::vector3 vCommandLocation; // polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego odnosi sie komenda // NOTE: not used
|
||||
TOrders OrderList[ maxorders ]; // lista rozkazów
|
||||
int OrderPos = 0,
|
||||
OrderTop = 0; // rozkaz aktualny oraz wolne miejsce do wstawiania nowych
|
||||
|
||||
// scantable
|
||||
// methods
|
||||
public:
|
||||
int CrossRoute(TTrack *tr);
|
||||
inline void MoveDistanceAdd( double distance ) {
|
||||
dMoveLen += distance * iDirection; } //jak jedzie do tyłu to trzeba uwzględniać, że distance jest ujemna
|
||||
private:
|
||||
// Ra: metody obsługujące skanowanie toru
|
||||
std::vector<basic_event *> CheckTrackEvent(TTrack *Track, double const fDirection ) const;
|
||||
std::vector<basic_event *> CheckTrackEvent( TTrack *Track, double const fDirection ) const;
|
||||
bool TableAddNew();
|
||||
bool TableNotFound(basic_event const *Event) const;
|
||||
void TableTraceRoute(double fDistance, TDynamicObject *pVehicle);
|
||||
void TableCheck(double fDistance);
|
||||
TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc);
|
||||
// modifies brake distance for low target speeds, to ease braking rate in such situations
|
||||
float
|
||||
braking_distance_multiplier( float const Targetvelocity ) const;
|
||||
bool TableNotFound( basic_event const *Event ) const;
|
||||
void TableTraceRoute( double fDistance, TDynamicObject *pVehicle );
|
||||
void TableCheck( double fDistance );
|
||||
TCommandType TableUpdate( double &fVelDes, double &fDist, double &fNext, double &fAcc );
|
||||
// returns most recently calculated distance to potential obstacle ahead
|
||||
double TrackBlock() const;
|
||||
void TablePurger();
|
||||
void TableSort();
|
||||
inline double MoveDistanceGet() const {
|
||||
return dMoveLen; }
|
||||
return dMoveLen;
|
||||
}
|
||||
inline void MoveDistanceReset() {
|
||||
dMoveLen = 0.0; }
|
||||
public:
|
||||
inline void MoveDistanceAdd(double distance) {
|
||||
dMoveLen += distance * iDirection; //jak jedzie do tyłu to trzeba uwzględniać, że distance jest ujemna
|
||||
dMoveLen = 0.0;
|
||||
}
|
||||
std::size_t TableSize() const { return sSpeedTable.size(); }
|
||||
void TableClear();
|
||||
int TableDirection() { return iTableDirection; }
|
||||
|
||||
private: // Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu
|
||||
bool BackwardTrackBusy(TTrack *Track);
|
||||
basic_event *CheckTrackEventBackward(double fDirection, TTrack *Track);
|
||||
TTrack *BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, basic_event *&Event);
|
||||
// Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu
|
||||
bool BackwardTrackBusy( TTrack *Track );
|
||||
basic_event *CheckTrackEventBackward( double fDirection, TTrack *Track );
|
||||
TTrack *BackwardTraceRoute( double &fDistance, double &fDirection, TTrack *Track, basic_event *&Event );
|
||||
void SetProximityVelocity( double dist, double vel, glm::dvec3 const *pos );
|
||||
TCommandType BackwardScan();
|
||||
|
||||
public:
|
||||
void PhysicsLog();
|
||||
std::string StopReasonText();
|
||||
~TController();
|
||||
void TakeControl(bool yes);
|
||||
Mtable::TTrainParameters const * TrainTimetable() const;
|
||||
std::string TrainName() const;
|
||||
std::string Relation() const;
|
||||
int StationCount() const;
|
||||
int StationIndex() const;
|
||||
bool IsStop() const;
|
||||
std::string NextStop() const;
|
||||
inline
|
||||
bool Primary() const {
|
||||
return ( ( iDrivigFlags & movePrimary ) != 0 ); };
|
||||
inline
|
||||
int DrivigFlags() const {
|
||||
return iDrivigFlags; };
|
||||
// returns most recently calculated distance to potential obstacle ahead
|
||||
double
|
||||
TrackBlock() const;
|
||||
void MoveTo(TDynamicObject *to);
|
||||
void DirectionInitial();
|
||||
std::string TableText(std::size_t const Index) const;
|
||||
int CrossRoute(TTrack *tr);
|
||||
/*
|
||||
void RouteSwitch(int d);
|
||||
*/
|
||||
std::string OwnerName() const;
|
||||
TMoverParameters const *Controlling() const {
|
||||
return mvControlling; }
|
||||
int Direction() const {
|
||||
return iDirection; }
|
||||
// members
|
||||
int iLast{ 0 }; // ostatnia wypełniona pozycja w tabeli <iFirst (modulo iSpeedTableSize)
|
||||
int iTableDirection{ 0 }; // kierunek zapełnienia tabelki względem pojazdu z AI
|
||||
std::vector<TSpeedPos> sSpeedTable;
|
||||
double fLastVel = 0.0; // prędkość na poprzednio sprawdzonym torze
|
||||
TTrack *tLast = nullptr; // ostatni analizowany tor
|
||||
basic_event *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu
|
||||
std::size_t SemNextIndex{ std::size_t(-1) };
|
||||
std::size_t SemNextStopIndex{ std::size_t( -1 ) };
|
||||
double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki
|
||||
basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2]
|
||||
|
||||
// timetable
|
||||
// methods
|
||||
public:
|
||||
std::string TrainName() const;
|
||||
private:
|
||||
std::string Relation() const;
|
||||
Mtable::TTrainParameters const * TrainTimetable() const;
|
||||
int StationIndex() const;
|
||||
int StationCount() const;
|
||||
bool IsStop() const;
|
||||
std::string NextStop() const;
|
||||
// members
|
||||
Mtable::TTrainParameters *TrainParams = nullptr; // rozkład jazdy zawsze jest, nawet jeśli pusty
|
||||
std::string asNextStop; // nazwa następnego punktu zatrzymania wg rozkładu
|
||||
int iStationStart = 0; // numer pierwszej stacji pokazywanej na podglądzie rozkładu
|
||||
double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku
|
||||
int iRadioChannel = 1; // numer aktualnego kanału radiowego
|
||||
int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia)
|
||||
sound_source tsGuardSignal { sound_placement::internal };
|
||||
|
||||
// consist
|
||||
// methods
|
||||
public:
|
||||
private:
|
||||
bool CheckVehicles(TOrders user = Wait_for_orders);
|
||||
bool PrepareEngine();
|
||||
bool ReleaseEngine();
|
||||
void Doors(bool const Open, int const Side = 0);
|
||||
// returns true if any vehicle in the consist has an open door
|
||||
bool doors_open() const;
|
||||
void AutoRewident(); // ustawia hamulce w składzie
|
||||
// members
|
||||
double fLength = 0.0; // długość składu (do wyciągania z ograniczeń)
|
||||
double fMass = 0.0; // całkowita masa do liczenia stycznej składowej grawitacji
|
||||
double fAccGravity = 0.0; // przyspieszenie składowej stycznej grawitacji
|
||||
int iVehicles = 0; // ilość pojazdów w składzie
|
||||
int iEngineActive = 0; // ABu: Czy silnik byl juz zalaczony; Ra: postęp w załączaniu
|
||||
bool IsCargoTrain{ false };
|
||||
bool IsHeavyCargoTrain{ false };
|
||||
bool IsLineBreakerClosed{ false }; // state of line breaker in all powered vehicles under control
|
||||
double fReady = 0.0; // poziom odhamowania wagonów
|
||||
bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow
|
||||
TDynamicObject *pVehicles[ 2 ]; // skrajne pojazdy w składzie (niekoniecznie bezpośrednio sterowane)
|
||||
|
||||
// logs
|
||||
// methods
|
||||
void PhysicsLog();
|
||||
void CloseLog();
|
||||
// members
|
||||
std::ofstream LogFile; // zapis parametrow fizycznych
|
||||
double LastUpdatedTime = 0.0; // czas od ostatniego logu
|
||||
double ElapsedTime = 0.0; // czas od poczatku logu
|
||||
|
||||
// getters
|
||||
public:
|
||||
TDynamicObject const *Vehicle() const {
|
||||
return pVehicle; }
|
||||
TDynamicObject *Vehicle( side const Side ) const {
|
||||
return pVehicles[ Side ]; }
|
||||
private:
|
||||
std::string OwnerName() const;
|
||||
|
||||
// leftovers
|
||||
/*
|
||||
int iRouteWanted = 3; // oczekiwany kierunek jazdy (0-stop,1-lewo,2-prawo,3-prosto) np. odpala migacz lub czeka na stan zwrotnicy
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
@@ -622,8 +622,12 @@ void
|
||||
TDynamicObject::toggle_lights() {
|
||||
|
||||
if( true == SectionLightsActive ) {
|
||||
// switch all lights off
|
||||
// switch all lights off...
|
||||
for( auto §ion : Sections ) {
|
||||
// ... but skip cab sections, their lighting ignores battery state
|
||||
auto const sectionname { section.compartment->pName };
|
||||
if( sectionname.find( "cab" ) == 0 ) { continue; }
|
||||
|
||||
section.light_level = 0.0f;
|
||||
}
|
||||
SectionLightsActive = false;
|
||||
|
||||
@@ -1370,6 +1370,7 @@ public:
|
||||
bool MotorBlowersSwitch( bool State, side const Side, range_t const Notify = range_t::consist ); // traction motor fan state toggle
|
||||
bool MotorBlowersSwitchOff( bool State, side const Side, range_t const Notify = range_t::consist ); // traction motor fan state toggle
|
||||
bool MainSwitch( bool const State, range_t const Notify = range_t::consist );/*! wylacznik glowny*/
|
||||
void MainSwitch_( bool const State );
|
||||
bool ConverterSwitch( bool State, range_t const Notify = range_t::consist );/*! wl/wyl przetwornicy*/
|
||||
bool CompressorSwitch( bool State, range_t const Notify = range_t::consist );/*! wl/wyl sprezarki*/
|
||||
|
||||
|
||||
@@ -490,7 +490,7 @@ int TMoverParameters::DettachStatus(int ConnectNo)
|
||||
// if (CouplerType==Articulated) return false; //sprzęg nie do rozpięcia - może być tylko urwany
|
||||
// Couplers[ConnectNo].CoupleDist=Distance(Loc,Couplers[ConnectNo].Connected->Loc,Dim,Couplers[ConnectNo].Connected->Dim);
|
||||
CouplerDist(ConnectNo);
|
||||
if (Couplers[ConnectNo].CouplerType == TCouplerType::Screw ? Couplers[ConnectNo].CoupleDist < 0.0 : true)
|
||||
if (Couplers[ConnectNo].CouplerType == TCouplerType::Screw ? Couplers[ConnectNo].CoupleDist < 0.01 : true)
|
||||
return -Couplers[ConnectNo].CouplingFlag; // można rozłączać, jeśli dociśnięty
|
||||
return (Couplers[ConnectNo].CoupleDist > 0.2) ? -Couplers[ConnectNo].CouplingFlag :
|
||||
Couplers[ConnectNo].CouplingFlag;
|
||||
@@ -563,7 +563,7 @@ bool TMoverParameters::DirectionForward()
|
||||
SendCtrlToNext("Direction", ActiveDir, CabNo);
|
||||
return true;
|
||||
}
|
||||
else if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT))
|
||||
else if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor))
|
||||
return MinCurrentSwitch(true); //"wysoki rozruch" EN57
|
||||
return false;
|
||||
};
|
||||
@@ -635,8 +635,9 @@ bool TMoverParameters::ChangeCab(int direction)
|
||||
{
|
||||
// if (ActiveCab+direction=0) then LastCab:=ActiveCab;
|
||||
ActiveCab = ActiveCab + direction;
|
||||
if ((BrakeSystem == TBrakeSystem::Pneumatic) && (BrakeCtrlPosNo > 0))
|
||||
{
|
||||
if( ( BrakeCtrlPosNo > 0 )
|
||||
&& ( ( BrakeSystem == TBrakeSystem::Pneumatic )
|
||||
|| ( BrakeSystem == TBrakeSystem::ElectroPneumatic ) ) ) {
|
||||
// if (BrakeHandle==FV4a) //!!!POBIERAĆ WARTOŚĆ Z KLASY ZAWORU!!!
|
||||
// BrakeLevelSet(-2); //BrakeCtrlPos=-2;
|
||||
// else if ((BrakeHandle==FVel6)||(BrakeHandle==St113))
|
||||
@@ -2399,7 +2400,7 @@ bool TMoverParameters::EpFuseSwitch(bool State)
|
||||
bool TMoverParameters::DirectionBackward(void)
|
||||
{
|
||||
bool DB = false;
|
||||
if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT))
|
||||
if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor))
|
||||
if (MinCurrentSwitch(false))
|
||||
{
|
||||
DB = true; //
|
||||
@@ -2739,66 +2740,76 @@ bool TMoverParameters::MotorBlowersSwitchOff( bool State, side const Side, range
|
||||
// Q: 20160713
|
||||
// włączenie / wyłączenie obwodu głownego
|
||||
// *************************************************************************************************
|
||||
bool TMoverParameters::MainSwitch( bool const State, range_t const Notify )
|
||||
{
|
||||
bool TMoverParameters::MainSwitch( bool const State, range_t const Notify ) {
|
||||
|
||||
bool const initialstate { Mains || dizel_startup };
|
||||
|
||||
if( ( Mains != State )
|
||||
&& ( MainCtrlPosNo > 0 ) ) {
|
||||
MainSwitch_( State );
|
||||
|
||||
if( ( false == State )
|
||||
|| ( ( ( ScndCtrlPos == 0 ) || ( EngineType == TEngineType::ElectricInductionMotor ) )
|
||||
&& ( ( ConvOvldFlag == false ) || ( TrainType == dt_EZT ) )
|
||||
&& ( true == NoVoltRelay )
|
||||
&& ( true == OvervoltageRelay )
|
||||
&& ( LastSwitchingTime > CtrlDelay )
|
||||
&& ( false == TestFlag( DamageFlag, dtrain_out ) )
|
||||
&& ( false == TestFlag( EngDmgFlag, 1 ) ) ) ) {
|
||||
|
||||
if( true == State ) {
|
||||
// switch on
|
||||
if( ( EngineType == TEngineType::DieselEngine )
|
||||
|| ( EngineType == TEngineType::DieselElectric ) ) {
|
||||
// launch diesel engine startup procedure
|
||||
dizel_startup = true;
|
||||
}
|
||||
else {
|
||||
Mains = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Mains = false;
|
||||
// potentially knock out the pumps if their switch doesn't force them on
|
||||
WaterPump.is_active &= WaterPump.is_enabled;
|
||||
FuelPump.is_active &= FuelPump.is_enabled;
|
||||
}
|
||||
|
||||
if( ( TrainType == dt_EZT )
|
||||
&& ( false == State ) ) {
|
||||
|
||||
ConvOvldFlag = true;
|
||||
}
|
||||
|
||||
if( Mains != initialstate ) {
|
||||
LastSwitchingTime = 0;
|
||||
}
|
||||
|
||||
if( Notify != range_t::local ) {
|
||||
// pass the command to other vehicles
|
||||
SendCtrlToNext(
|
||||
"MainSwitch",
|
||||
( State ? 1 : 0 ),
|
||||
CabNo,
|
||||
( Notify == range_t::unit ?
|
||||
coupling::control | coupling::permanent :
|
||||
coupling::control ) );
|
||||
}
|
||||
}
|
||||
if( Notify != range_t::local ) {
|
||||
// pass the command to other vehicles
|
||||
// TBD: pass the requested state, or the actual state?
|
||||
SendCtrlToNext(
|
||||
"MainSwitch",
|
||||
( State ? 1 : 0 ),
|
||||
CabNo,
|
||||
( Notify == range_t::unit ?
|
||||
coupling::control | coupling::permanent :
|
||||
coupling::control ) );
|
||||
}
|
||||
|
||||
return ( ( Mains || dizel_startup ) != initialstate );
|
||||
}
|
||||
|
||||
void TMoverParameters::MainSwitch_( bool const State ) {
|
||||
|
||||
if( ( Mains == State )
|
||||
|| ( MainCtrlPosNo == 0 ) ) {
|
||||
// nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
bool const initialstate { Mains || dizel_startup };
|
||||
|
||||
if( ( false == State )
|
||||
|| ( ( ( ScndCtrlPos == 0 ) || ( EngineType == TEngineType::ElectricInductionMotor ) )
|
||||
&& ( ( ConvOvldFlag == false ) || ( TrainType == dt_EZT ) )
|
||||
&& ( true == NoVoltRelay )
|
||||
&& ( true == OvervoltageRelay )
|
||||
&& ( LastSwitchingTime > CtrlDelay )
|
||||
&& ( false == TestFlag( DamageFlag, dtrain_out ) )
|
||||
&& ( false == TestFlag( EngDmgFlag, 1 ) ) ) ) {
|
||||
|
||||
if( true == State ) {
|
||||
// switch on
|
||||
if( ( EngineType == TEngineType::DieselEngine )
|
||||
|| ( EngineType == TEngineType::DieselElectric ) ) {
|
||||
// launch diesel engine startup procedure
|
||||
dizel_startup = true;
|
||||
}
|
||||
else {
|
||||
Mains = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Mains = false;
|
||||
// potentially knock out the pumps if their switch doesn't force them on
|
||||
WaterPump.is_active &= WaterPump.is_enabled;
|
||||
FuelPump.is_active &= FuelPump.is_enabled;
|
||||
}
|
||||
|
||||
if( ( TrainType == dt_EZT )
|
||||
&& ( false == State ) ) {
|
||||
|
||||
ConvOvldFlag = true;
|
||||
}
|
||||
|
||||
if( Mains != initialstate ) {
|
||||
LastSwitchingTime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
// Q: 20160713
|
||||
// włączenie / wyłączenie przetwornicy
|
||||
@@ -3555,9 +3566,8 @@ void TMoverParameters::UpdatePipePressure(double dt)
|
||||
|
||||
dpMainValve = 0;
|
||||
|
||||
if ((BrakeCtrlPosNo > 1) /*&& (ActiveCab != 0)*/)
|
||||
// with BrakePressureTable[BrakeCtrlPos] do
|
||||
{
|
||||
if( BrakeCtrlPosNo > 1 ) {
|
||||
|
||||
if ((EngineType != TEngineType::ElectricInductionMotor))
|
||||
dpLocalValve = LocHandle->GetPF(std::max(LocalBrakePosA, LocalBrakePosAEIM), Hamulec->GetBCP(), ScndPipePress, dt, 0);
|
||||
else
|
||||
@@ -3573,13 +3583,21 @@ void TMoverParameters::UpdatePipePressure(double dt)
|
||||
temp = ScndPipePress;
|
||||
}
|
||||
Handle->SetReductor(BrakeCtrlPos2);
|
||||
|
||||
if( ( ( BrakeOpModes & bom_PS ) == 0 )
|
||||
|| ( ( ActiveCab != 0 )
|
||||
&& ( BrakeOpModeFlag != bom_PS ) ) ) {
|
||||
|
||||
if ((BrakeOpModeFlag != bom_PS))
|
||||
if ((BrakeOpModeFlag < bom_EP) || ((Handle->GetPos(bh_EB) - 0.5) < BrakeCtrlPosR) ||
|
||||
(BrakeHandle != TBrakeHandle::MHZ_EN57))
|
||||
dpMainValve = Handle->GetPF(BrakeCtrlPosR, PipePress, temp, dt, EqvtPipePress);
|
||||
else
|
||||
dpMainValve = Handle->GetPF(0, PipePress, temp, dt, EqvtPipePress);
|
||||
if( ( BrakeOpModeFlag < bom_EP )
|
||||
|| ( ( Handle->GetPos( bh_EB ) - 0.5 ) < BrakeCtrlPosR )
|
||||
|| ( ( BrakeHandle != TBrakeHandle::MHZ_EN57 )
|
||||
&& ( BrakeHandle != TBrakeHandle::MHZ_K8P ) ) ) {
|
||||
dpMainValve = Handle->GetPF( BrakeCtrlPosR, PipePress, temp, dt, EqvtPipePress );
|
||||
}
|
||||
else {
|
||||
dpMainValve = Handle->GetPF( 0, PipePress, temp, dt, EqvtPipePress );
|
||||
}
|
||||
}
|
||||
|
||||
if (dpMainValve < 0) // && (PipePressureVal > 0.01) //50
|
||||
if (Compressor > ScndPipePress)
|
||||
@@ -4627,14 +4645,6 @@ double TMoverParameters::TractionForce( double dt ) {
|
||||
switch( EngineType ) {
|
||||
|
||||
case TEngineType::ElectricSeriesMotor: {
|
||||
/*
|
||||
if ((Mains)) // nie wchodzić w funkcję bez potrzeby
|
||||
if ( (std::max(GetTrainsetVoltage(), std::abs(Voltage)) < EnginePowerSource.CollectorParameters.MinV) ||
|
||||
(std::max(GetTrainsetVoltage(), std::abs(Voltage)) * EnginePowerSource.CollectorParameters.OVP >
|
||||
EnginePowerSource.CollectorParameters.MaxV))
|
||||
if( MainSwitch( false, ( TrainType == dt_EZT ? range_t::unit : range_t::local ) ) ) // TODO: check whether we need to send this EMU-wide
|
||||
EventFlag = true; // wywalanie szybkiego z powodu niewłaściwego napięcia
|
||||
*/
|
||||
// update the state of voltage relays
|
||||
auto const voltage { std::max( GetTrainsetVoltage(), std::abs( RunningTraction.TractionVoltage ) ) };
|
||||
NoVoltRelay = ( voltage >= EnginePowerSource.CollectorParameters.MinV );
|
||||
@@ -4646,6 +4656,18 @@ double TMoverParameters::TractionForce( double dt ) {
|
||||
break;
|
||||
}
|
||||
|
||||
case TEngineType::ElectricInductionMotor: {
|
||||
// TODO: check if we can use instead the code for electricseriesmotor
|
||||
if( ( Mains ) ) {
|
||||
// nie wchodzić w funkcję bez potrzeby
|
||||
if( ( std::max( GetTrainsetVoltage(), std::abs( RunningTraction.TractionVoltage ) ) < EnginePowerSource.CollectorParameters.MinV )
|
||||
|| ( std::max( GetTrainsetVoltage(), std::abs( RunningTraction.TractionVoltage ) ) > EnginePowerSource.CollectorParameters.MaxV + 200 ) ) {
|
||||
MainSwitch( false, ( TrainType == dt_EZT ? range_t::unit : range_t::local ) ); // TODO: check whether we need to send this EMU-wide
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TEngineType::DieselElectric: {
|
||||
// TODO: move this to the auto relay check when the electric engine code paths are unified
|
||||
StLinFlag = MotorConnectorsCheck();
|
||||
@@ -5062,13 +5084,6 @@ double TMoverParameters::TractionForce( double dt ) {
|
||||
|
||||
case TEngineType::ElectricInductionMotor:
|
||||
{
|
||||
if( ( Mains ) ) {
|
||||
// nie wchodzić w funkcję bez potrzeby
|
||||
if( ( std::max( std::abs( Voltage ), GetTrainsetVoltage() ) < EnginePowerSource.CollectorParameters.MinV )
|
||||
|| ( std::max( std::abs( Voltage ), GetTrainsetVoltage() ) > EnginePowerSource.CollectorParameters.MaxV + 200 ) ) {
|
||||
MainSwitch( false, ( TrainType == dt_EZT ? range_t::unit : range_t::local ) ); // TODO: check whether we need to send this EMU-wide
|
||||
}
|
||||
}
|
||||
if( true == Mains ) {
|
||||
//tempomat
|
||||
if (ScndCtrlPosNo > 1)
|
||||
@@ -5531,8 +5546,9 @@ bool TMoverParameters::MaxCurrentSwitch(bool State)
|
||||
bool TMoverParameters::MinCurrentSwitch(bool State)
|
||||
{
|
||||
bool MCS = false;
|
||||
if (((EngineType == TEngineType::ElectricSeriesMotor) && (IminHi > IminLo)) || (TrainType == dt_EZT))
|
||||
{
|
||||
if( ( ( EngineType == TEngineType::ElectricSeriesMotor ) && ( IminHi > IminLo ) )
|
||||
|| ( ( TrainType == dt_EZT ) && ( EngineType != TEngineType::ElectricInductionMotor ) ) ) {
|
||||
|
||||
if (State && (Imin == IminLo))
|
||||
{
|
||||
Imin = IminHi;
|
||||
@@ -9461,22 +9477,7 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
||||
}
|
||||
else if (Command == "MainSwitch")
|
||||
{
|
||||
if (CValue1 == 1) {
|
||||
|
||||
if( ( EngineType == TEngineType::DieselEngine )
|
||||
|| ( EngineType == TEngineType::DieselElectric ) ) {
|
||||
dizel_startup = true;
|
||||
}
|
||||
else {
|
||||
Mains = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Mains = false;
|
||||
// potentially knock out the pumps if their switch doesn't force them on
|
||||
WaterPump.is_active &= WaterPump.is_enabled;
|
||||
FuelPump.is_active &= FuelPump.is_enabled;
|
||||
}
|
||||
MainSwitch_( CValue1 > 0.0 );
|
||||
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||
}
|
||||
else if (Command == "Direction")
|
||||
|
||||
23
Model3d.cpp
23
Model3d.cpp
@@ -174,10 +174,26 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
||||
/*
|
||||
iVboPtr = Pos; // pozycja w VBO
|
||||
*/
|
||||
if (!parser.expectToken("type:"))
|
||||
ErrorLog("Bad model: expected submodel type definition not found while loading model \"" + Model->NameGet() + "\"" );
|
||||
auto token { parser.getToken<std::string>() };
|
||||
if( token != "type:" ) {
|
||||
std::string errormessage {
|
||||
"Bad model: expected submodel type definition not found while loading model \"" + Model->NameGet() + "\""
|
||||
+ "\ncurrent model data stream content: \"" };
|
||||
auto count { 10 };
|
||||
while( ( true == parser.getTokens() )
|
||||
&& ( false == ( token = parser.peek() ).empty() )
|
||||
&& ( token != "parent:" ) ) {
|
||||
// skip data until next submodel, dump first few tokens in the error message
|
||||
if( --count > 0 ) {
|
||||
errormessage += token + " ";
|
||||
}
|
||||
}
|
||||
errormessage += "(...)\"";
|
||||
ErrorLog( errormessage );
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
std::string type = parser.getToken<std::string>();
|
||||
auto const type { parser.getToken<std::string>() };
|
||||
if (type == "mesh")
|
||||
eType = GL_TRIANGLES; // submodel - trójkaty
|
||||
else if (type == "point")
|
||||
@@ -190,7 +206,6 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
||||
eType = TP_STARS; // wiele punktów świetlnych
|
||||
};
|
||||
parser.ignoreToken();
|
||||
std::string token;
|
||||
parser.getTokens(1, false); // nazwa submodelu bez zmieny na małe
|
||||
parser >> token;
|
||||
Name(token);
|
||||
|
||||
12
PyInt.cpp
12
PyInt.cpp
@@ -99,13 +99,11 @@ auto python_taskqueue::init() -> bool {
|
||||
stringioclassname != nullptr ?
|
||||
PyObject_CallObject( stringioclassname, nullptr ) :
|
||||
nullptr );
|
||||
m_error = { (
|
||||
m_stderr = { (
|
||||
stringioobject == nullptr ? nullptr :
|
||||
PySys_SetObject( "stderr", stringioobject ) != 0 ? nullptr :
|
||||
stringioobject ) };
|
||||
|
||||
if( m_error == nullptr ) { goto release_and_exit; }
|
||||
|
||||
if( false == run_file( "abstractscreenrenderer" ) ) { goto release_and_exit; }
|
||||
|
||||
// release the lock, save the state for future use
|
||||
@@ -325,13 +323,13 @@ python_taskqueue::error() {
|
||||
|
||||
if( PyErr_Occurred() == nullptr ) { return; }
|
||||
|
||||
if( m_error != nullptr ) {
|
||||
if( m_stderr != nullptr ) {
|
||||
// std err pythona jest buforowane
|
||||
PyErr_Print();
|
||||
auto *errortext { PyObject_CallMethod( m_error, "getvalue", nullptr ) };
|
||||
auto *errortext { PyObject_CallMethod( m_stderr, "getvalue", nullptr ) };
|
||||
ErrorLog( PyString_AsString( errortext ) );
|
||||
// czyscimy bufor na kolejne bledy
|
||||
PyObject_CallMethod( m_error, "truncate", "i", 0 );
|
||||
PyObject_CallMethod( m_stderr, "truncate", "i", 0 );
|
||||
}
|
||||
else {
|
||||
// nie dziala buffor pythona
|
||||
@@ -353,7 +351,7 @@ python_taskqueue::error() {
|
||||
}
|
||||
auto *tracebacktext { PyObject_Str( traceback ) };
|
||||
if( tracebacktext != nullptr ) {
|
||||
WriteLog( PyString_AsString( tracebacktext ) );
|
||||
ErrorLog( PyString_AsString( tracebacktext ) );
|
||||
}
|
||||
else {
|
||||
WriteLog( "Python Interpreter: failed to retrieve the stack traceback" );
|
||||
|
||||
2
PyInt.h
2
PyInt.h
@@ -93,7 +93,7 @@ private:
|
||||
void error();
|
||||
// members
|
||||
PyObject *m_main { nullptr };
|
||||
PyObject *m_error { nullptr };
|
||||
PyObject *m_stderr { nullptr };
|
||||
PyThreadState *m_mainthread{ nullptr };
|
||||
worker_array m_workers;
|
||||
threading::condition_variable m_condition; // wakes up the workers
|
||||
|
||||
65
Train.cpp
65
Train.cpp
@@ -547,13 +547,18 @@ PyObject *TTrain::GetTrainState() {
|
||||
PyDict_SetItemString( dict, "velnext", PyGetFloat( driver->VelNext ) );
|
||||
PyDict_SetItemString( dict, "actualproximitydist", PyGetFloat( driver->ActualProximityDist ) );
|
||||
// train data
|
||||
auto const *timetable{ driver->TrainTimetable() };
|
||||
|
||||
PyDict_SetItemString( dict, "trainnumber", PyGetString( driver->TrainName().c_str() ) );
|
||||
PyDict_SetItemString( dict, "train_brakingmassratio", PyGetFloat( timetable->BrakeRatio ) );
|
||||
PyDict_SetItemString( dict, "train_enginetype", PyGetString( timetable->LocSeries.c_str() ) );
|
||||
PyDict_SetItemString( dict, "train_engineload", PyGetFloat( timetable->LocLoad ) );
|
||||
|
||||
PyDict_SetItemString( dict, "train_stationindex", PyGetInt( driver->StationIndex() ) );
|
||||
auto const stationcount { driver->StationCount() };
|
||||
PyDict_SetItemString( dict, "train_stationcount", PyGetInt( stationcount ) );
|
||||
if( stationcount > 0 ) {
|
||||
// timetable stations data, if there's any
|
||||
auto const *timetable { driver->TrainTimetable() };
|
||||
for( auto stationidx = 1; stationidx <= stationcount; ++stationidx ) {
|
||||
auto const stationlabel { "train_station" + std::to_string( stationidx ) + "_" };
|
||||
auto const &timetableline { timetable->TimeTable[ stationidx ] };
|
||||
@@ -567,7 +572,9 @@ PyObject *TTrain::GetTrainState() {
|
||||
PyDict_SetItemString( dict, ( stationlabel + "dm" ).c_str(), PyGetInt( timetableline.Dm ) );
|
||||
}
|
||||
}
|
||||
PyDict_SetItemString( dict, "train_atpassengerstop", PyGetBool( driver->IsAtPassengerStop ) );
|
||||
// world state data
|
||||
PyDict_SetItemString( dict, "scenario", PyGetString( Global.SceneryFile.c_str() ) );
|
||||
PyDict_SetItemString( dict, "hours", PyGetInt( simulation::Time.data().wHour ) );
|
||||
PyDict_SetItemString( dict, "minutes", PyGetInt( simulation::Time.data().wMinute ) );
|
||||
PyDict_SetItemString( dict, "seconds", PyGetInt( simulation::Time.second() ) );
|
||||
@@ -811,7 +818,7 @@ void TTrain::OnCommand_secondcontrollerincrease( TTrain *Train, command_data con
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
// on press or hold
|
||||
if( ( Train->mvControlled->EngineType == TEngineType::DieselElectric )
|
||||
&& ( true == Train->mvControlled->ShuntMode ) ) {
|
||||
&& ( true == Train->mvControlled->ShuntMode ) ) {
|
||||
Train->mvControlled->AnPos = clamp(
|
||||
Train->mvControlled->AnPos + 0.025,
|
||||
0.0, 1.0 );
|
||||
@@ -905,6 +912,9 @@ void TTrain::OnCommand_secondcontrollerdecreasefast( TTrain *Train, command_data
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_secondcontrollerset( TTrain *Train, command_data const &Command ) {
|
||||
if (Command.action == GLFW_RELEASE)
|
||||
return;
|
||||
|
||||
auto const targetposition { std::min<int>( Command.param1, Train->mvControlled->ScndCtrlPosNo ) };
|
||||
while( ( targetposition < Train->mvControlled->GetVirtualScndPos() )
|
||||
&& ( true == Train->mvControlled->DecScndCtrl( 1 ) ) ) {
|
||||
@@ -966,10 +976,13 @@ void TTrain::OnCommand_independentbrakedecreasefast( TTrain *Train, command_data
|
||||
|
||||
void TTrain::OnCommand_independentbrakeset( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
Train->mvControlled->LocalBrakePosA = (
|
||||
clamp(
|
||||
Command.param1,
|
||||
0.0, 1.0 ) );
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
|
||||
Train->mvControlled->LocalBrakePosA = (
|
||||
clamp(
|
||||
Command.param1,
|
||||
0.0, 1.0 ) );
|
||||
}
|
||||
/*
|
||||
Train->mvControlled->LocalBrakePos = (
|
||||
std::round(
|
||||
@@ -1351,13 +1364,11 @@ void TTrain::OnCommand_trainbrakeoperationmodeincrease(TTrain *Train, command_da
|
||||
if( ( ( Train->mvOccupied->BrakeOpModeFlag << 1 ) & Train->mvOccupied->BrakeOpModes ) != 0 ) {
|
||||
// next mode
|
||||
Train->mvOccupied->BrakeOpModeFlag <<= 1;
|
||||
// audio feedback
|
||||
Train->dsbPneumaticSwitch.play();
|
||||
// visual feedback
|
||||
Train->ggBrakeOperationModeCtrl.UpdateValue(
|
||||
Train->mvOccupied->BrakeOpModeFlag > 0 ?
|
||||
std::log2( Train->mvOccupied->BrakeOpModeFlag ) :
|
||||
0 );
|
||||
0 ); // audio fallback
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1369,8 +1380,6 @@ void TTrain::OnCommand_trainbrakeoperationmodedecrease(TTrain *Train, command_da
|
||||
if( ( ( Train->mvOccupied->BrakeOpModeFlag >> 1 ) & Train->mvOccupied->BrakeOpModes ) != 0 ) {
|
||||
// previous mode
|
||||
Train->mvOccupied->BrakeOpModeFlag >>= 1;
|
||||
// audio feedback
|
||||
Train->dsbPneumaticSwitch.play();
|
||||
// visual feedback
|
||||
Train->ggBrakeOperationModeCtrl.UpdateValue(
|
||||
Train->mvOccupied->BrakeOpModeFlag > 0 ?
|
||||
@@ -5423,8 +5432,8 @@ bool TTrain::Update( double const Deltatime )
|
||||
btLampkaRadioStop.Turn( mvOccupied->Radio && mvOccupied->RadioStopFlag );
|
||||
btLampkaHamulecReczny.Turn(mvOccupied->ManualBrakePos > 0);
|
||||
// NBMX wrzesien 2003 - drzwi oraz sygnał odjazdu
|
||||
btLampkaDoorLeft.Turn(mvOccupied->DoorLeftOpened);
|
||||
btLampkaDoorRight.Turn(mvOccupied->DoorRightOpened);
|
||||
btLampkaDoorLeft.Turn( DynamicObject->dDoorMoveL > 0.0 );// mvOccupied->DoorLeftOpened);
|
||||
btLampkaDoorRight.Turn( DynamicObject->dDoorMoveR > 0.0 ); //mvOccupied ->DoorRightOpened);
|
||||
btLampkaBlokadaDrzwi.Turn(mvOccupied->DoorBlockedFlag());
|
||||
btLampkaDoorLockOff.Turn( false == mvOccupied->DoorLockEnabled );
|
||||
btLampkaDepartureSignal.Turn( mvControlled->DepartureSignal );
|
||||
@@ -5733,7 +5742,12 @@ bool TTrain::Update( double const Deltatime )
|
||||
InstrumentLightType == 0 ? mvControlled->Battery || mvControlled->ConverterFlag :
|
||||
InstrumentLightType == 1 ? mvControlled->Mains :
|
||||
InstrumentLightType == 2 ? mvControlled->ConverterFlag :
|
||||
InstrumentLightType == 3 ? mvControlled->Battery || mvControlled->ConverterFlag :
|
||||
false ) };
|
||||
if( InstrumentLightType == 3 ) {
|
||||
// TODO: link the light state with the state of the master key
|
||||
InstrumentLightActive = true;
|
||||
}
|
||||
btInstrumentLight.Turn( InstrumentLightActive && lightpower );
|
||||
btDashboardLight.Turn( DashboardLightActive && lightpower );
|
||||
btTimetableLight.Turn( TimetableLightActive && lightpower );
|
||||
@@ -5791,7 +5805,9 @@ bool TTrain::Update( double const Deltatime )
|
||||
ggHornLowButton.Update();
|
||||
ggHornHighButton.Update();
|
||||
ggWhistleButton.Update();
|
||||
ggHelperButton.UpdateValue(DynamicObject->Mechanik->HelperState);
|
||||
if( DynamicObject->Mechanik != nullptr ) {
|
||||
ggHelperButton.UpdateValue( DynamicObject->Mechanik->HelperState );
|
||||
}
|
||||
ggHelperButton.Update();
|
||||
for( auto &universal : ggUniversals ) {
|
||||
universal.Update();
|
||||
@@ -5859,7 +5875,8 @@ bool TTrain::Update( double const Deltatime )
|
||||
|
||||
// NOTE: crude way to have the pantographs go back up if they're dropped due to insufficient pressure etc
|
||||
// TODO: rework it into something more elegant, when redoing the whole consist/unit/cab etc arrangement
|
||||
if( DynamicObject->Mechanik != nullptr && !DynamicObject->Mechanik->AIControllFlag ) {
|
||||
if( ( DynamicObject->Mechanik == nullptr )
|
||||
|| ( false == DynamicObject->Mechanik->AIControllFlag ) ) {
|
||||
// don't mess with the ai driving, at least not while switches don't follow ai-set vehicle state
|
||||
if( ( mvControlled->Battery )
|
||||
|| ( mvControlled->ConverterFlag ) ) {
|
||||
@@ -7284,8 +7301,8 @@ void TTrain::set_cab_controls( int const Cab ) {
|
||||
0.f ) );
|
||||
// doors
|
||||
// NOTE: we're relying on the cab models to have switches reversed for the rear cab(?)
|
||||
ggDoorLeftButton.PutValue( mvOccupied->DoorLeftOpened ? 1.f : 0.f );
|
||||
ggDoorRightButton.PutValue( mvOccupied->DoorRightOpened ? 1.f : 0.f );
|
||||
ggDoorLeftButton.PutValue( /*mvOccupied->DoorLeftOpened*/ DynamicObject->dDoorMoveL > 0.0 ? 1.f : 0.f );
|
||||
ggDoorRightButton.PutValue( /*mvOccupied->DoorRightOpened*/ DynamicObject->dDoorMoveR > 0.0 ? 1.f : 0.f );
|
||||
// door lock
|
||||
ggDoorSignallingButton.PutValue(
|
||||
mvOccupied->DoorLockEnabled ?
|
||||
@@ -7491,14 +7508,18 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
||||
btInstrumentLight.Load( Parser, DynamicObject );
|
||||
InstrumentLightType = 0;
|
||||
}
|
||||
else if( Label == "i-instrumentlight_M:" ) {
|
||||
else if( Label == "i-instrumentlight_m:" ) {
|
||||
btInstrumentLight.Load( Parser, DynamicObject );
|
||||
InstrumentLightType = 1;
|
||||
}
|
||||
else if( Label == "i-instrumentlight_C:" ) {
|
||||
else if( Label == "i-instrumentlight_c:" ) {
|
||||
btInstrumentLight.Load( Parser, DynamicObject );
|
||||
InstrumentLightType = 2;
|
||||
}
|
||||
else if( Label == "i-instrumentlight_a:" ) {
|
||||
btInstrumentLight.Load( Parser, DynamicObject );
|
||||
InstrumentLightType = 3;
|
||||
}
|
||||
else if (Label == "i-doors:")
|
||||
{
|
||||
int i = Parser.getToken<int>() - 1;
|
||||
@@ -7734,6 +7755,12 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
gauge.Load(Parser, DynamicObject, 0.1);
|
||||
gauge.AssignDouble(&mvOccupied->PipePress);
|
||||
}
|
||||
else if( Label == "scndpress:" ) {
|
||||
// manometr przewodu hamulcowego
|
||||
auto &gauge = Cabine[ Cabindex ].Gauge( -1 ); // pierwsza wolna gałka
|
||||
gauge.Load( Parser, DynamicObject, 0.1 );
|
||||
gauge.AssignDouble( &mvOccupied->ScndPipePress );
|
||||
}
|
||||
else if (Label == "limpipepress:")
|
||||
{
|
||||
// manometr zbiornika sterujacego zaworu maszynisty
|
||||
|
||||
2
Train.h
2
Train.h
@@ -509,7 +509,7 @@ public: // reszta może by?publiczna
|
||||
TButton btInstrumentLight;
|
||||
TButton btDashboardLight;
|
||||
TButton btTimetableLight;
|
||||
int InstrumentLightType{ 0 }; // ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw.
|
||||
int InstrumentLightType{ 0 }; // ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw., 3-rozrzad
|
||||
bool InstrumentLightActive{ false };
|
||||
bool DashboardLightActive{ false };
|
||||
bool TimetableLightActive{ false };
|
||||
|
||||
@@ -480,6 +480,9 @@ drivermouse_input::default_bindings() {
|
||||
{ "brakeprofiler_sw:", {
|
||||
user_command::brakeactingspeedsetrapid,
|
||||
user_command::brakeactingspeedsetpassenger } },
|
||||
{ "brakeopmode_sw:", {
|
||||
user_command::trainbrakeoperationmodeincrease,
|
||||
user_command::trainbrakeoperationmodedecrease } },
|
||||
{ "maxcurrent_sw:", {
|
||||
user_command::motoroverloadrelaythresholdtoggle,
|
||||
user_command::none } },
|
||||
|
||||
@@ -443,8 +443,8 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
||||
std::abs( mover.enrot ) * 60,
|
||||
std::abs( mover.nrot ) * mover.Transmision.Ratio * 60,
|
||||
mover.RventRot * 60,
|
||||
mover.MotorBlowers[side::front].revolutions,
|
||||
mover.MotorBlowers[side::rear].revolutions,
|
||||
std::abs( mover.MotorBlowers[side::front].revolutions ),
|
||||
std::abs( mover.MotorBlowers[side::rear].revolutions ),
|
||||
mover.dizel_heat.rpmw,
|
||||
mover.dizel_heat.rpmw2 );
|
||||
|
||||
@@ -470,6 +470,7 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
||||
// brakes
|
||||
mover.fBrakeCtrlPos,
|
||||
mover.LocalBrakePosA,
|
||||
mover.BrakeOpModeFlag,
|
||||
update_vehicle_brake().c_str(),
|
||||
mover.LoadFlag,
|
||||
// cylinders
|
||||
@@ -482,7 +483,7 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
||||
mover.ScndPipePress,
|
||||
mover.CntrlPipePress,
|
||||
// tanks
|
||||
mover.Volume,
|
||||
mover.Hamulec->GetBRP(),
|
||||
mover.Compressor,
|
||||
mover.Hamulec->GetCRP() );
|
||||
|
||||
@@ -526,37 +527,7 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
||||
vehicle.GetPosition().z );
|
||||
|
||||
Output.emplace_back( m_buffer.data(), Global.UITextColor );
|
||||
/*
|
||||
textline = " TC:" + to_string( mover.TotalCurrent, 0 );
|
||||
*/
|
||||
/*
|
||||
if( mover.ManualBrakePos > 0 ) {
|
||||
|
||||
textline += "; manual brake on";
|
||||
}
|
||||
*/
|
||||
/*
|
||||
// McZapkie: warto wiedziec w jakim stanie sa przelaczniki
|
||||
switch(
|
||||
mover.ActiveDir *
|
||||
( mover.Imin == mover.IminLo ?
|
||||
1 :
|
||||
2 ) ) {
|
||||
case 2: { textline += " >> "; break; }
|
||||
case 1: { textline += " -> "; break; }
|
||||
case 0: { textline += " -- "; break; }
|
||||
case -1: { textline += " <- "; break; }
|
||||
case -2: { textline += " << "; break; }
|
||||
}
|
||||
|
||||
// McZapkie: komenda i jej parametry
|
||||
if( mover.CommandIn.Command != ( "" ) ) {
|
||||
textline =
|
||||
"C:" + mover.CommandIn.Command
|
||||
+ " V1=" + to_string( mover.CommandIn.Value1, 0 )
|
||||
+ " V2=" + to_string( mover.CommandIn.Value2, 0 );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
std::string
|
||||
@@ -899,7 +870,10 @@ debug_panel::render_section( std::string const &Header, std::vector<text_line> c
|
||||
if( false == ImGui::CollapsingHeader( Header.c_str() ) ) { return false; }
|
||||
|
||||
for( auto const &line : Lines ) {
|
||||
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||
ImGui::PushStyleColor( ImGuiCol_Text, { line.color.r, line.color.g, line.color.b, line.color.a } );
|
||||
ImGui::TextUnformatted( line.data.c_str() );
|
||||
ImGui::PopStyleColor();
|
||||
// ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -190,11 +190,13 @@ opengl_vbogeometrybank::draw_( gfx::geometry_handle const &Geometry, gfx::stream
|
||||
m_buffercapacity = datasize;
|
||||
}
|
||||
// actual draw procedure starts here
|
||||
auto &chunkrecord { m_chunkrecords[ Geometry.chunk - 1 ] };
|
||||
// sanity check; shouldn't be needed but, eh
|
||||
if( chunkrecord.size == 0 ) { return; }
|
||||
// setup...
|
||||
if( m_activebuffer != m_buffer ) {
|
||||
bind_buffer();
|
||||
}
|
||||
auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ];
|
||||
auto const &chunk = gfx::geometry_bank::chunk( Geometry );
|
||||
if( false == chunkrecord.is_good ) {
|
||||
// we may potentially need to upload new buffer data before we can draw it
|
||||
|
||||
17
renderer.cpp
17
renderer.cpp
@@ -580,7 +580,9 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
// without rain/snow we can render the cab early to limit the overdraw
|
||||
if( ( false == FreeFlyModeFlag )
|
||||
&& ( Global.Overcast <= 1.f ) ) { // precipitation happens when overcast is in 1-2 range
|
||||
#ifdef EU07_DISABLECABREFLECTIONS
|
||||
switch_units( true, true, false );
|
||||
#endif
|
||||
setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix );
|
||||
// cache shadow colour in case we need to account for cab light
|
||||
auto const shadowcolor { m_shadowcolor };
|
||||
@@ -603,7 +605,9 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
Render_precipitation();
|
||||
// cab render
|
||||
if( false == FreeFlyModeFlag ) {
|
||||
#ifdef EU07_DISABLECABREFLECTIONS
|
||||
switch_units( true, true, false );
|
||||
#endif
|
||||
setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix );
|
||||
// cache shadow colour in case we need to account for cab light
|
||||
auto const shadowcolor{ m_shadowcolor };
|
||||
@@ -2612,7 +2616,8 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
// material configuration:
|
||||
Bind_Material( null_handle );
|
||||
// limit impact of dense fog on the lights
|
||||
::glFogf( GL_FOG_DENSITY, static_cast<GLfloat>( 1.0 / std::min<float>( Global.fFogEnd, m_fogrange * 2 ) ) );
|
||||
auto const lightrange { std::max<float>( 500, m_fogrange * 2 ) }; // arbitrary, visibility at least 750m
|
||||
::glFogf( GL_FOG_DENSITY, static_cast<GLfloat>( 1.0 / lightrange ) );
|
||||
|
||||
::glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_POINT_BIT );
|
||||
::glDisable( GL_LIGHTING );
|
||||
@@ -3147,7 +3152,8 @@ opengl_renderer::Render_Alpha( TAnimModel *Instance ) {
|
||||
|
||||
void
|
||||
opengl_renderer::Render_Alpha( TTraction *Traction ) {
|
||||
|
||||
/*
|
||||
// NOTE: test disabled as this call is only executed as part of the colour pass
|
||||
double distancesquared;
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
case rendermode::shadows: {
|
||||
@@ -3160,6 +3166,8 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
auto const distancesquared { glm::length2( ( Traction->location() - m_renderpass.camera.position() ) / (double)Global.ZoomFactor ) / Global.fDistanceFactor };
|
||||
if( ( distancesquared < Traction->m_rangesquaredmin )
|
||||
|| ( distancesquared >= Traction->m_rangesquaredmax ) ) {
|
||||
return;
|
||||
@@ -3208,7 +3216,8 @@ void
|
||||
opengl_renderer::Render_Alpha( scene::lines_node const &Lines ) {
|
||||
|
||||
auto const &data { Lines.data() };
|
||||
|
||||
/*
|
||||
// NOTE: test disabled as this call is only executed as part of the colour pass
|
||||
double distancesquared;
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
case rendermode::shadows: {
|
||||
@@ -3221,6 +3230,8 @@ opengl_renderer::Render_Alpha( scene::lines_node const &Lines ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
auto const distancesquared { glm::length2( ( data.area.center - m_renderpass.camera.position() ) / (double)Global.ZoomFactor ) / Global.fDistanceFactor };
|
||||
if( ( distancesquared < data.rangesquared_min )
|
||||
|| ( distancesquared >= data.rangesquared_max ) ) {
|
||||
return;
|
||||
|
||||
@@ -25,6 +25,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
//#define EU07_USE_DEBUG_CABSHADOWMAP
|
||||
//#define EU07_USE_DEBUG_CAMERA
|
||||
//#define EU07_USE_DEBUG_SOUNDEMITTERS
|
||||
//#define EU07_DISABLECABREFLECTIONS
|
||||
|
||||
struct opengl_light : public basic_light {
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ scenarioloader_mode::init() {
|
||||
bool
|
||||
scenarioloader_mode::update() {
|
||||
|
||||
WriteLog( "\nLoading scenario..." );
|
||||
WriteLog( "\nLoading scenario \"" + Global.SceneryFile + "\"..." );
|
||||
|
||||
auto timestart = std::chrono::system_clock::now();
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ init() {
|
||||
"Controllers:\n master: %d(%d), secondary: %s\nEngine output: %.1f, current: %.0f\nRevolutions:\n engine: %.0f, motors: %.0f\n engine fans: %.0f, motor fans: %.0f+%.0f, cooling fans: %.0f+%.0f",
|
||||
" (shunt mode)",
|
||||
"\nTemperatures:\n engine: %.2f, oil: %.2f, water: %.2f%c%.2f",
|
||||
"Brakes:\n train: %.2f, independent: %.2f, delay: %s, load flag: %d\nBrake cylinder pressures:\n train: %.2f, independent: %.2f, status: 0x%.2x\nPipe pressures:\n brake: %.2f (hat: %.2f), main: %.2f, control: %.2f\nTank pressures:\n auxiliary: %.2f, main: %.2f, control: %.2f",
|
||||
"Brakes:\n train: %.2f, independent: %.2f, mode: %d, delay: %s, load flag: %d\nBrake cylinder pressures:\n train: %.2f, independent: %.2f, status: 0x%.2x\nPipe pressures:\n brake: %.2f (hat: %.2f), main: %.2f, control: %.2f\nTank pressures:\n auxiliary: %.2f, main: %.2f, control: %.2f",
|
||||
" pantograph: %.2f%cMT",
|
||||
"Forces:\n tractive: %.1f, brake: %.1f, friction: %.2f%s\nAcceleration:\n tangential: %.2f, normal: %.2f (path radius: %s)\nVelocity: %.2f, distance traveled: %.2f\nPosition: [%.2f, %.2f, %.2f]",
|
||||
|
||||
@@ -72,6 +72,7 @@ init() {
|
||||
"brake acting speed",
|
||||
"brake acting speed: cargo",
|
||||
"brake acting speed: rapid",
|
||||
"brake operation mode",
|
||||
"motor overload relay threshold",
|
||||
"water pump",
|
||||
"water pump breaker",
|
||||
@@ -194,7 +195,7 @@ init() {
|
||||
"Nastawniki:\n glowny: %d(%d), dodatkowy: %s\nMoc silnika: %.1f, prad silnika: %.0f\nObroty:\n silnik: %.0f, motory: %.0f\n went.silnika: %.0f, went.motorow: %.0f+%.0f, went.chlodnicy: %.0f+%.0f",
|
||||
" (tryb manewrowy)",
|
||||
"\nTemperatury:\n silnik: %.2f, olej: %.2f, woda: %.2f%c%.2f",
|
||||
"Hamulce:\n zespolony: %.2f, pomocniczy: %.2f, nastawa: %s, ladunek: %d\nCisnienie w cylindrach:\n zespolony: %.2f, pomocniczy: %.2f, status: 0x%.2x\nCisnienia w przewodach:\n glowny: %.2f (kapturek: %.2f), zasilajacy: %.2f, kontrolny: %.2f\nCisnienia w zbiornikach:\n pomocniczy: %.2f, glowny: %.2f, sterujacy: %.2f",
|
||||
"Hamulce:\n zespolony: %.2f, pomocniczy: %.2f, tryb: %d, nastawa: %s, ladunek: %d\nCisnienie w cylindrach:\n zespolony: %.2f, pomocniczy: %.2f, status: 0x%.2x\nCisnienia w przewodach:\n glowny: %.2f (kapturek: %.2f), zasilajacy: %.2f, kontrolny: %.2f\nCisnienia w zbiornikach:\n pomocniczy: %.2f, glowny: %.2f, sterujacy: %.2f",
|
||||
" pantograf: %.2f%cZG",
|
||||
"Sily:\n napedna: %.1f, hamowania: %.1f, tarcie: %.2f%s\nPrzyspieszenia:\n styczne: %.2f, normalne: %.2f (promien: %s)\nPredkosc: %.2f, pokonana odleglosc: %.2f\nPozycja: [%.2f, %.2f, %.2f]",
|
||||
|
||||
@@ -209,6 +210,7 @@ init() {
|
||||
"nastawa hamulca",
|
||||
"nastawa hamulca: towarowy",
|
||||
"nastawa hamulca: pospieszny",
|
||||
"tryb pracy hamulca",
|
||||
"zakres pradu rozruchu",
|
||||
"pompa wody",
|
||||
"wylacznik samoczynny pompy wody",
|
||||
@@ -318,6 +320,7 @@ init() {
|
||||
"brakeprofile_sw:",
|
||||
"brakeprofileg_sw:",
|
||||
"brakeprofiler_sw:",
|
||||
"brakeopmode_sw:",
|
||||
"maxcurrent_sw:",
|
||||
"waterpump_sw:",
|
||||
"waterpumpbreaker_sw:",
|
||||
|
||||
@@ -61,6 +61,7 @@ enum string {
|
||||
cab_brakeprofile_sw,
|
||||
cab_brakeprofileg_sw,
|
||||
cab_brakeprofiler_sw,
|
||||
cab_brakeopmode_sw,
|
||||
cab_maxcurrent_sw,
|
||||
cab_waterpump_sw,
|
||||
cab_waterpumpbreaker_sw,
|
||||
|
||||
Reference in New Issue
Block a user