diff --git a/Classes.h b/Classes.h index 91c68acb..5bafa69d 100644 --- a/Classes.h +++ b/Classes.h @@ -36,7 +36,9 @@ class TMtableTime; // czas dla danego posterunku }; class TController; // obiekt sterujący pociągiem (AI) +#ifdef EU07_USE_OLD_TNAMES_CLASS class TNames; // obiekt sortujący nazwy +#endif typedef enum { // binarne odpowiedniki komend w komórce pamięci diff --git a/Driver.cpp b/Driver.cpp index 30acad7a..d4069481 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -160,7 +160,7 @@ void TSpeedPos::CommandCheck() case cm_PassengerStopPoint: // nie ma dostępu do rozkładu // przystanek, najwyżej AI zignoruje przy analizie tabelki - if ((iFlags & spPassengerStopPoint) == 0) +// if ((iFlags & spPassengerStopPoint) == 0) fVelNext = 0.0; // TrainParams->IsStop()?0.0:-1.0; //na razie tak iFlags |= spPassengerStopPoint; // niestety nie da się w tym miejscu współpracować z rozkładem break; @@ -829,7 +829,8 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN { // o ile dana pozycja tabelki jest istotna if (sSpeedTable[i].iFlags & spPassengerStopPoint) { // jeśli przystanek, trzeba obsłużyć wg rozkładu - if (sSpeedTable[i].evEvent->CommandGet() != asNextStop) + // first 19 chars of the command is expected to be "PassengerStopPoint:" so we skip them + if ( ToLower(sSpeedTable[i].evEvent->CommandGet()).compare( 19, sizeof(asNextStop), ToLower(asNextStop)) != 0 ) { // jeśli nazwa nie jest zgodna if (sSpeedTable[i].fDist < -fLength) // jeśli został przejechany sSpeedTable[i].iFlags = @@ -856,8 +857,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN // licznika) ma przesunąć na // następny postój TrainParams->UpdateMTable( - GlobalTime->hh, GlobalTime->mm, - asNextStop.substr(19, asNextStop.length())); + GlobalTime->hh, GlobalTime->mm, asNextStop); TrainParams->StationIndexInc(); // przejście do następnej asNextStop = TrainParams->NextStop(); // pobranie kolejnego miejsca zatrzymania @@ -956,8 +956,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN // opóźnia również kierownika } if (TrainParams->UpdateMTable( - GlobalTime->hh, GlobalTime->mm, - asNextStop.substr(19, asNextStop.length()))) + GlobalTime->hh, GlobalTime->mm, asNextStop) ) { // to się wykona tylko raz po zatrzymaniu na W4 if (TrainParams->CheckTrainLatency() < 0.0) iDrivigFlags |= moveLate; // odnotowano spóźnienie @@ -1277,8 +1276,8 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN VelSignal = -1.0; // aby stojący ruszył if (sSpeedTable[i].fDist < 0.0) // jeśli przejechany { - if (v != 0 ? VelSignal = -1.0 : VelSignal = 0.0) - ; // ustawienie, gdy przejechany jest lepsze niż + VelSignal = (v != 0 ? -1.0 : 0.0); + // ustawienie, gdy przejechany jest lepsze niż // wcale, ale to jeszcze nie to if (sSpeedTable[i].iFlags & spEvent) // jeśli event if ((sSpeedTable[i].evEvent != eSignSkip) ? @@ -2323,15 +2322,15 @@ bool TController::IncBrake() { case Individual: if (mvOccupied->LocalBrake == ManualBrake) - OK = mvOccupied->IncManualBrakeLevel(1 + floor(0.5 + fabs(AccDesired))); + OK = mvOccupied->IncManualBrakeLevel( 1 + static_cast( std::floor( 0.5 + std::fabs(AccDesired))) ); else - OK = mvOccupied->IncLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired))); + OK = mvOccupied->IncLocalBrakeLevel( 1 + static_cast( std::floor( 0.5 + std::fabs(AccDesired))) ); break; case Pneumatic: if ((mvOccupied->Couplers[0].Connected == NULL) && (mvOccupied->Couplers[1].Connected == NULL)) OK = mvOccupied->IncLocalBrakeLevel( - 1 + floor(0.5 + fabs(AccDesired))); // hamowanie lokalnym bo luzem jedzie + 1 + static_cast( std::floor( 0.5 + std::fabs(AccDesired))) ); // hamowanie lokalnym bo luzem jedzie else { if (mvOccupied->BrakeCtrlPos + 1 == mvOccupied->BrakeCtrlPosNo) @@ -2438,7 +2437,8 @@ bool TController::IncSpeed() if (tsGuardSignal->GetStatus() & DSBSTATUS_PLAYING) // jeśli gada, to nie jedziemy return false; bool OK = true; - if (iDrivigFlags & moveDoorOpened) + if ((iDrivigFlags & moveDoorOpened) + &&(mvOccupied->Vel > 0.1)) // added velocity threshold to prevent door shuffle on stop Doors(false); // zamykanie drzwi - tutaj wykonuje tylko AI (zmienia fActionTime) if (fActionTime < 0.0) // gdy jest nakaz poczekać z jazdą, to nie ruszać return false; @@ -4184,6 +4184,12 @@ bool TController::UpdateSituation(double dt) { // komunikat od kierownika tu, bo musi być wolna droga i odczekany czas // stania iDrivigFlags &= ~moveGuardSignal; // tylko raz nadać + + if( iDrivigFlags & moveDoorOpened ) // jeśli drzwi otwarte + if( !mvOccupied + ->DoorOpenCtrl ) // jeśli drzwi niesterowane przez maszynistę + Doors( false ); // a EZT zamknie dopiero po odegraniu komunikatu kierownika + tsGuardSignal->Stop(); // w zasadzie to powinien mieć flagę, czy jest dźwiękiem radiowym, czy // bezpośrednim @@ -4207,11 +4213,6 @@ bool TController::UpdateSituation(double dt) 1.0, 0, true, pVehicle->GetPosition()); // dźwięk niby przez radio } - if (iDrivigFlags & moveDoorOpened) // jeśli drzwi otwarte - if (!mvOccupied - ->DoorOpenCtrl) // jeśli drzwi niesterowane przez maszynistę - Doors(false); // a EZT zamknie dopiero po odegraniu komunikatu - // kierownika } if (mvOccupied->V == 0.0) AbsAccS = fAccGravity; // Ra 2014-03: jesli skład stoi, to działa na niego @@ -5238,19 +5239,24 @@ TCommandType TController::BackwardScan() std::string TController::NextStop() { // informacja o następnym zatrzymaniu, wyświetlane pod [F1] - if (asNextStop.length() < 19) + if (asNextStop == "[End of route]") return ""; // nie zawiera nazwy stacji, gdy dojechał do końca // dodać godzinę odjazdu if (!TrainParams) return ""; // tu nie powinno nigdy wejść + std::string nextstop = asNextStop; TMTableLine *t = TrainParams->TimeTable + TrainParams->StationIndex; - if (t->Dh >= 0) // jeśli jest godzina odjazdu - return asNextStop.substr(19, 30) + " " + std::to_string(t->Dh) + ":" + - std::to_string(t->Dm); // odjazd - else if (t->Ah >= 0) // przyjazd - return asNextStop.substr(19, 30) + " (" + std::to_string(t->Ah) + ":" + - std::to_string(t->Am) + ")"; // przyjazd - return ""; + if( t->Ah >= 0 ) { + // przyjazd + nextstop += " przyj." + std::to_string( t->Ah ) + ":" + + ( t->Am < 10 ? "0" : "" ) + std::to_string( t->Am ); + } + if( t->Dh >= 0 ) { + // jeśli jest godzina odjazdu + nextstop += " odj." + std::to_string( t->Dh ) + ":" + + ( t->Dm < 10 ? "0" : "" ) + std::to_string( t->Dm ); + } + return nextstop; }; //-----------koniec skanowania semaforow diff --git a/Driver.h b/Driver.h index b2e8a586..4f27d920 100644 --- a/Driver.h +++ b/Driver.h @@ -387,7 +387,7 @@ class TController bool IsStop(); bool Primary() { - return this ? bool(iDrivigFlags & movePrimary) : false; + return this ? ((iDrivigFlags & movePrimary) != 0) : false; }; int inline DrivigFlags() { diff --git a/DynObj.cpp b/DynObj.cpp index fe185581..7c4618e0 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -1873,13 +1873,13 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424" { if (Cab == 0) MoverParameters->BrakeCtrlPos = - floor(MoverParameters->Handle->GetPos(bh_NP)); + static_cast( std::floor(MoverParameters->Handle->GetPos(bh_NP)) ); else - MoverParameters->BrakeCtrlPos = floor(MoverParameters->Handle->GetPos(bh_RP)); + MoverParameters->BrakeCtrlPos = static_cast( std::floor(MoverParameters->Handle->GetPos(bh_RP)) ); } else MoverParameters->BrakeCtrlPos = - floor(MoverParameters->Handle->GetPos(bh_NP)); + static_cast( std::floor(MoverParameters->Handle->GetPos(bh_NP)) ); MoverParameters->BrakeLevelSet( MoverParameters->BrakeCtrlPos); // poprawienie hamulca po ewentualnym @@ -2920,7 +2920,7 @@ bool TDynamicObject::Update(double dt, double dt1) // 1. najpierw daj kazdemu tyle samo int i = 0; for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p; - (kier > 0 ? p = p->NextC(4) : p = p->PrevC(4))) + p = (kier == true ? p->NextC(4) : p->PrevC(4)) ) { float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] - p->MoverParameters->BrakeCylSpring) * @@ -2948,7 +2948,7 @@ bool TDynamicObject::Update(double dt, double dt1) i = 0; float przek = 0; for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p; - (kier > 0 ? p = p->NextC(4) : p = p->PrevC(4))) + p = (kier == true ? p->NextC(4) : p->PrevC(4)) ) { if ((FzEP[i] > 0.01) && (FzEP[i] > @@ -3302,13 +3302,16 @@ bool TDynamicObject::Update(double dt, double dt1) switch (i) // numer pantografu { // trzeba usunąć to rozróżnienie case 0: - if (Global::bLiveTraction ? false : - !p->hvPowerWire) // jeśli nie ma drutu, może pooszukiwać + if( ( Global::bLiveTraction == false ) + && ( p->hvPowerWire == nullptr ) ) { + // jeśli nie ma drutu, może pooszukiwać MoverParameters->PantFrontVolt = - (p->PantWys >= 1.2) ? 0.95 * MoverParameters->EnginePowerSource.MaxVoltage : - 0.0; - else if (MoverParameters->PantFrontUp ? (PantDiff < 0.01) : - false) // tolerancja niedolegania + ( p->PantWys >= 1.2 ) ? + 0.95 * MoverParameters->EnginePowerSource.MaxVoltage : + 0.0; + } + else if( ( true == MoverParameters->PantFrontUp ) + && ( PantDiff < 0.01 ) ) // tolerancja niedolegania { if ((MoverParameters->PantFrontVolt == 0.0) && (MoverParameters->PantRearVolt == 0.0)) @@ -3328,12 +3331,16 @@ bool TDynamicObject::Update(double dt, double dt1) MoverParameters->PantFrontVolt = 0.0; break; case 1: - if (Global::bLiveTraction ? false : - !p->hvPowerWire) // jeśli nie ma drutu, może pooszukiwać + if( ( false == Global::bLiveTraction ) + && ( nullptr == p->hvPowerWire ) ) { + // jeśli nie ma drutu, może pooszukiwać MoverParameters->PantRearVolt = - (p->PantWys >= 1.2) ? 0.95 * MoverParameters->EnginePowerSource.MaxVoltage : - 0.0; - else if (MoverParameters->PantRearUp ? (PantDiff < 0.01) : false) + ( p->PantWys >= 1.2 ) ? + 0.95 * MoverParameters->EnginePowerSource.MaxVoltage : + 0.0; + } + else if ( ( true == MoverParameters->PantRearUp ) + && ( PantDiff < 0.01 ) ) { if ((MoverParameters->PantRearVolt == 0.0) && (MoverParameters->PantFrontVolt == 0.0)) @@ -4372,7 +4379,6 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName, pants = NULL; // wskaźnik pierwszego obiektu animującego dla pantografów cParser parser( TypeName + ".mmd", cParser::buffer_FILE, BaseDir ); std::string token; - int i; do { token = ""; parser.getTokens(); parser >> token; @@ -4387,7 +4393,8 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName, iMultiTex = 1; asModel.erase( asModel.length() - 1 ); } - if ((i = asModel.find(',')) != std::string::npos) + std::size_t i = asModel.find( ',' ); + if ( i != std::string::npos ) { // Ra 2015-01: może szukać przecinka w // nazwie modelu, a po przecinku była by // liczba @@ -5910,7 +5917,7 @@ TDynamicObject::ConnectedEnginePowerSource( TDynamicObject const *Caller ) const // NOTE: the order should be reversed in flipped vehicles, but we ignore this out of laziness if( ( nullptr != NextConnected ) && ( NextConnected != Caller ) - && ( MoverParameters->Couplers[1].CouplingFlag & ctrain_controll == ctrain_controll ) ) { + && ( ( MoverParameters->Couplers[1].CouplingFlag & ctrain_controll ) == ctrain_controll ) ) { auto source = NextConnected->ConnectedEnginePowerSource( this ); if( source != TPowerSource::NotDefined ) { @@ -5921,7 +5928,7 @@ TDynamicObject::ConnectedEnginePowerSource( TDynamicObject const *Caller ) const // ...then rear... if( ( nullptr != PrevConnected ) && ( PrevConnected != Caller ) - && ( MoverParameters->Couplers[ 0 ].CouplingFlag & ctrain_controll == ctrain_controll ) ) { + && ( ( MoverParameters->Couplers[ 0 ].CouplingFlag & ctrain_controll ) == ctrain_controll ) ) { auto source = PrevConnected->ConnectedEnginePowerSource( this ); if( source != TPowerSource::NotDefined ) { diff --git a/EU07.cpp b/EU07.cpp index f46fd78a..367afaa8 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -39,6 +39,7 @@ Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others #pragma comment( lib, "winmm.lib" ) #pragma comment( lib, "setupapi.lib" ) #pragma comment( lib, "python27.lib" ) +#pragma comment (lib, "dbghelp.lib") HDC hDC = NULL; // Private GDI Device Context HGLRC hRC = NULL; // Permanent Rendering Context @@ -567,6 +568,55 @@ LRESULT CALLBACK WndProc(HWND hWnd, // handle for this window return DefWindowProc(hWnd, uMsg, wParam, lParam); }; +#ifdef _WINDOWS +void make_minidump( ::EXCEPTION_POINTERS* e ) { + + auto hDbgHelp = ::LoadLibraryA( "dbghelp" ); + if( hDbgHelp == nullptr ) + return; + auto pMiniDumpWriteDump = (decltype( &MiniDumpWriteDump ))::GetProcAddress( hDbgHelp, "MiniDumpWriteDump" ); + if( pMiniDumpWriteDump == nullptr ) + return; + + char name[ MAX_PATH ]; + { + auto nameEnd = name + ::GetModuleFileNameA( ::GetModuleHandleA( 0 ), name, MAX_PATH ); + ::SYSTEMTIME t; + ::GetSystemTime( &t ); + wsprintfA( nameEnd - strlen( ".exe" ), + "_crashdump_%4d%02d%02d_%02d%02d%02d.dmp", + t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond ); + } + + auto hFile = ::CreateFileA( name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 ); + if( hFile == INVALID_HANDLE_VALUE ) + return; + + ::MINIDUMP_EXCEPTION_INFORMATION exceptionInfo; + exceptionInfo.ThreadId = ::GetCurrentThreadId(); + exceptionInfo.ExceptionPointers = e; + exceptionInfo.ClientPointers = FALSE; + + auto dumped = pMiniDumpWriteDump( + ::GetCurrentProcess(), + ::GetCurrentProcessId(), + hFile, + ::MINIDUMP_TYPE( ::MiniDumpWithIndirectlyReferencedMemory | ::MiniDumpScanMemory ), + e ? &exceptionInfo : nullptr, + nullptr, + nullptr ); + + ::CloseHandle( hFile ); + + return; +} + +LONG CALLBACK unhandled_handler( ::EXCEPTION_POINTERS* e ) { + make_minidump( e ); + return EXCEPTION_CONTINUE_SEARCH; +} +#endif + int WINAPI WinMain(HINSTANCE hInstance, // instance HINSTANCE hPrevInstance, // previous instance LPSTR lpCmdLine, // command line parameters @@ -581,6 +631,9 @@ int WINAPI WinMain(HINSTANCE hInstance, // instance // this will turn on FPE for #IND and zerodiv state = _control87( state & ~( _EM_ZERODIVIDE | _EM_INVALID ), _MCW_EM ); #endif +#ifdef _WINDOWS + ::SetUnhandledExceptionFilter( unhandled_handler ); +#endif MSG msg; // windows message structure BOOL done = FALSE; // bool variable to exit loop diff --git a/Event.cpp b/Event.cpp index e50d1857..5ea1ddf5 100644 --- a/Event.cpp +++ b/Event.cpp @@ -316,7 +316,7 @@ void TEvent::Load(cParser *parser, vector3 *org) if (token.substr(0, 19) == "PassengerStopPoint:") { if (token.find('#') != std::string::npos) - token = token.substr(0, token.find('#') - 1); // obcięcie unikatowości + token.erase(token.find('#')); // obcięcie unikatowości bEnabled = false; // nie do kolejki (dla SetVelocity też, ale jak jest do toru // dowiązany) Params[6].asCommand = cm_PassengerStopPoint; diff --git a/Ground.cpp b/Ground.cpp index 1015efe4..f3c0af7f 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -1308,8 +1308,9 @@ TGround::TGround() for( int i = 0; i < TP_LAST; ++i ) { nRootOfType[ i ] = nullptr; // zerowanie tablic wyszukiwania } +#ifdef EU07_USE_OLD_TNAMES_CLASS sTracks = new TNames(); // nazwy torów - na razie tak - +#endif ::SecureZeroMemory( TempConnectionType, sizeof( TempConnectionType ) ); ::SecureZeroMemory( pRendered, sizeof( pRendered ) ); } @@ -1348,7 +1349,9 @@ void TGround::Free() iNumNodes = 0; // RootNode=NULL; nRootDynamic = NULL; +#ifdef EU07_USE_OLD_TNAMES_CLASS delete sTracks; +#endif } TGroundNode * TGround::DynamicFindAny(std::string asNameToFind) @@ -1381,7 +1384,38 @@ TGroundNode * TGround::FindGroundNode(std::string asNameToFind, TGroundNodeType { // wyszukiwanie obiektu o podanej nazwie i konkretnym typie if ((iNodeType == TP_TRACK) || (iNodeType == TP_MEMCELL) || (iNodeType == TP_MODEL)) { // wyszukiwanie w drzewie binarnym +#ifdef EU07_USE_OLD_TNAMES_CLASS return (TGroundNode *)sTracks->Find(iNodeType, asNameToFind.c_str()); +#else +/* + switch( iNodeType ) { + + case TP_TRACK: { + auto const lookup = m_trackmap.find( asNameToFind ); + return + lookup != m_trackmap.end() ? + lookup->second : + nullptr; + } + case TP_MODEL: { + auto const lookup = m_modelmap.find( asNameToFind ); + return + lookup != m_modelmap.end() ? + lookup->second : + nullptr; + } + case TP_MEMCELL: { + auto const lookup = m_memcellmap.find( asNameToFind ); + return + lookup != m_memcellmap.end() ? + lookup->second : + nullptr; + } + } + return nullptr; +*/ + return m_trackmap.Find( iNodeType, asNameToFind ); +#endif } // standardowe wyszukiwanie liniowe TGroundNode *Current; @@ -1705,6 +1739,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser) tmp->MemCell->Load(parser); if (!tmp->asName.empty()) // jest pusta gdy "none" { // dodanie do wyszukiwarki +#ifdef EU07_USE_OLD_TNAMES_CLASS if (sTracks->Update(TP_MEMCELL, tmp->asName.c_str(), tmp)) // najpierw sprawdzić, czy już jest { // przy zdublowaniu wskaźnik zostanie podmieniony w drzewku na późniejszy (zgodność @@ -1713,6 +1748,12 @@ TGroundNode * TGround::AddGroundNode(cParser *parser) } else sTracks->Add(TP_MEMCELL, tmp->asName.c_str(), tmp); // nazwa jest unikalna +#else + if( false == m_trackmap.Add( TP_MEMCELL, tmp->asName, tmp ) ) { + // przy zdublowaniu wskaźnik zostanie podmieniony w drzewku na późniejszy (zgodność wsteczna) + ErrorLog( "Duplicated memcell: " + tmp->asName ); // to zgłaszać duplikat + } +#endif } break; case TP_EVLAUNCH: @@ -1732,6 +1773,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser) tmp->asName); // w nazwie może być nazwa odcinka izolowanego if (!tmp->asName.empty()) // jest pusta gdy "none" { // dodanie do wyszukiwarki +#ifdef EU07_USE_OLD_TNAMES_CLASS if (sTracks->Update(TP_TRACK, tmp->asName.c_str(), tmp)) // najpierw sprawdzić, czy już jest { // przy zdublowaniu wskaźnik zostanie podmieniony w drzewku na późniejszy (zgodność @@ -1741,6 +1783,12 @@ TGroundNode * TGround::AddGroundNode(cParser *parser) } else sTracks->Add(TP_TRACK, tmp->asName.c_str(), tmp); // nazwa jest unikalna +#else + if( false == m_trackmap.Add( TP_TRACK, tmp->asName, tmp ) ) { + // przy zdublowaniu wskaźnik zostanie podmieniony w drzewku na późniejszy (zgodność wsteczna) + ErrorLog( "Duplicated track: " + tmp->asName ); // to zgłaszać duplikat + } +#endif } tmp->pCenter = (tmp->pTrack->CurrentSegment()->FastGetPoint_0() + tmp->pTrack->CurrentSegment()->FastGetPoint(0.5) + @@ -1981,6 +2029,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser) } else if (!tmp->asName.empty()) // jest pusta gdy "none" { // dodanie do wyszukiwarki +#ifdef EU07_USE_OLD_TNAMES_CLASS if (sTracks->Update(TP_MODEL, tmp->asName.c_str(), tmp)) // najpierw sprawdzić, czy już jest { // przy zdublowaniu wskaźnik zostanie podmieniony w drzewku na późniejszy (zgodność @@ -1989,6 +2038,12 @@ TGroundNode * TGround::AddGroundNode(cParser *parser) } else sTracks->Add(TP_MODEL, tmp->asName.c_str(), tmp); // nazwa jest unikalna +#else + if( false == m_trackmap.Add( TP_MODEL, tmp->asName, tmp ) ) { + // przy zdublowaniu wskaźnik zostanie podmieniony w drzewku na późniejszy (zgodność wsteczna) + ErrorLog( "Duplicated model: " + tmp->asName ); // to zgłaszać duplikat + } +#endif } // str=Parser->GetNextSymbol().LowerCase(); break; @@ -2268,7 +2323,15 @@ TSubRect * TGround::GetSubRect(int iCol, int iRow) TEvent * TGround::FindEvent(const string &asEventName) { +#ifdef EU07_USE_OLD_TNAMES_CLASS return (TEvent *)sTracks->Find(0, asEventName.c_str()); // wyszukiwanie w drzewie +#else + auto const lookup = m_eventmap.find( asEventName ); + return + lookup != m_eventmap.end() ? + lookup->second : + nullptr; +#endif /* //powolna wyszukiwarka for (TEvent *Current=RootEvent;Current;Current=Current->Next2) { @@ -2281,13 +2344,25 @@ TEvent * TGround::FindEvent(const string &asEventName) TEvent * TGround::FindEventScan(const string &asEventName) { // wyszukanie eventu z opcją utworzenia niejawnego dla komórek skanowanych - TEvent *e = (TEvent *)sTracks->Find(0, asEventName.c_str()); // wyszukiwanie w drzewie eventów +#ifdef EU07_USE_OLD_TNAMES_CLASS + TEvent *e = (TEvent *)sTracks->Find( 0, asEventName.c_str() ); // wyszukiwanie w drzewie eventów +#else + auto const lookup = m_eventmap.find( asEventName ); + auto e = + lookup != m_eventmap.end() ? + lookup->second : + nullptr; +#endif if (e) return e; // jak istnieje, to w porządku if (asEventName.rfind(":scan") != std::string::npos) // jeszcze może być event niejawny { // no to szukamy komórki pamięci o nazwie zawartej w evencie string n = asEventName.substr(0, asEventName.length() - 5); // do dwukropka - if (sTracks->Find(TP_MEMCELL, n.c_str())) // jeśli jest takowa komórka pamięci +#ifdef EU07_USE_OLD_TNAMES_CLASS + if( sTracks->Find( TP_MEMCELL, n.c_str() ) ) // jeśli jest takowa komórka pamięci +#else + if( m_trackmap.Find( TP_MEMCELL, n ) != nullptr ) // jeśli jest takowa komórka pamięci +#endif e = new TEvent(n); // utworzenie niejawnego eventu jej odczytu } return e; // utworzony albo się nie udało @@ -2626,7 +2701,11 @@ bool TGround::Init(std::string asFile, HDC hDC) if (RootEvent->asName.find( "onstart") != string::npos) // event uruchamiany automatycznie po starcie AddToQuery(RootEvent, NULL); // dodanie do kolejki +#ifdef EU07_USE_OLD_TNAMES_CLASS sTracks->Add(0, tmp->asName.c_str(), tmp); // dodanie do wyszukiwarki +#else + m_eventmap.emplace( tmp->asName, tmp ); // dodanie do wyszukiwarki +#endif } } } @@ -2905,10 +2984,12 @@ bool TGround::Init(std::string asFile, HDC hDC) parser >> token; } +#ifdef EU07_USE_OLD_TNAMES_CLASS sTracks->Sort(TP_TRACK); // finalne sortowanie drzewa torów sTracks->Sort(TP_MEMCELL); // finalne sortowanie drzewa komórek pamięci sTracks->Sort(TP_MODEL); // finalne sortowanie drzewa modeli sTracks->Sort(0); // finalne sortowanie drzewa eventów +#endif if (!bInitDone) FirstInit(); // jeśli nie było w scenerii if (Global::pTerrainCompact) @@ -3375,7 +3456,11 @@ void TGround::InitTracks() Current = new TGroundNode(); // to nie musi mieć nazwy, nazwa w wyszukiwarce wystarczy // Current->asName=p->asName; //mazwa identyczna, jak nazwa odcinka izolowanego Current->MemCell = new TMemCell(NULL); // nowa komórka +#ifdef EU07_USE_OLD_TNAMES_CLASS sTracks->Add(TP_MEMCELL, p->asName.c_str(), Current); // dodanie do wyszukiwarki +#else + m_trackmap.Add( TP_MEMCELL, p->asName, Current ); +#endif Current->nNext = nRootOfType[TP_MEMCELL]; // to nie powinno tutaj być, bo robi się śmietnik nRootOfType[TP_MEMCELL] = Current; @@ -4038,15 +4123,16 @@ bool TGround::CheckQuery() } #endif //if (DebugModeFlag) - WriteLog("Type: UpdateValues & Track command - " + - std::string(tmpEvent->Params[0].asText) + " " + - std::to_string(tmpEvent->Params[1].asdouble) + " " + - std::to_string(tmpEvent->Params[2].asdouble)); + WriteLog("Type: UpdateValues & Track command - " + + tmpEvent->Params[5].asMemCell->Text() + " " + + std::to_string( tmpEvent->Params[ 5 ].asMemCell->Value1() ) + " " + + std::to_string( tmpEvent->Params[ 5 ].asMemCell->Value2() ) ); } - else //if (DebugModeFlag) - WriteLog("Type: UpdateValues - " + std::string( tmpEvent->Params[0].asText ) + - " " + std::to_string(tmpEvent->Params[1].asdouble) + " " + - std::to_string(tmpEvent->Params[2].asdouble)); + else //if (DebugModeFlag) + WriteLog("Type: UpdateValues - " + + tmpEvent->Params[5].asMemCell->Text() + " " + + std::to_string( tmpEvent->Params[ 5 ].asMemCell->Value1() ) + " " + + std::to_string( tmpEvent->Params[ 5 ].asMemCell->Value2() ) ); } break; case tp_GetValues: diff --git a/Ground.h b/Ground.h index c314ce6e..099eff67 100644 --- a/Ground.h +++ b/Ground.h @@ -15,6 +15,7 @@ http://mozilla.org/MPL/2.0/. #include "Classes.h" #include "ResourceManager.h" #include "dumb3d.h" +#include "Names.h" using namespace Math3D; @@ -297,7 +298,15 @@ class TGround ssh = 0, ssm = 0; // ustawienia czasu // int tracks,tracksfar; //liczniki torów +#ifdef EU07_USE_OLD_TNAMES_CLASS TNames *sTracks = nullptr; // posortowane nazwy torów i eventów +#else + typedef std::unordered_map event_map; +// typedef std::unordered_map groundnode_map; + event_map m_eventmap; +// groundnode_map m_memcellmap, m_modelmap, m_trackmap; + TNames m_trackmap; +#endif private: // metody prywatne bool EventConditon(TEvent *e); diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 116fc599..01c3104e 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -543,8 +543,6 @@ struct TTransmision enum TCouplerType { NoCoupler, Articulated, Bare, Chain, Screw, Automatic }; -//class TMoverParameters; // wyforwardowanie klasy coby typ byl widoczny w ponizszej strukturze - struct TCoupling { /*parametry*/ double SpringKB = 1.0; /*stala sprezystosci zderzaka/sprzegu, %tlumiennosci */ @@ -673,7 +671,7 @@ public: int MainCtrlPosNo = 0; /*ilosc pozycji nastawnika*/ int ScndCtrlPosNo = 0; int LightsPosNo = 0; // NOTE: values higher than 0 seem to break the current code for light switches - int LightsDefPos = 0; + int LightsDefPos = 1; bool LightsWrap = false; int Lights[2][17]; // pozycje świateł, przód - tył, 1 .. 16 bool ScndInMain = false; /*zaleznosc bocznika od nastawnika*/ @@ -748,7 +746,7 @@ public: /*- dla lokomotyw z silnikami indukcyjnymi -*/ double eimc[26]; /*-dla wagonow*/ - long MaxLoad = 0.0; /*masa w T lub ilosc w sztukach - ladownosc*/ + double MaxLoad = 0.0; /*masa w T lub ilosc w sztukach - ladownosc*/ std::string LoadAccepted; std::string LoadQuantity; /*co moze byc zaladowane, jednostki miary*/ double OverLoadFactor = 0.0; /*ile razy moze byc przekroczona ladownosc*/ double LoadSpeed = 0.0; double UnLoadSpeed = 0.0;/*szybkosc na- i rozladunku jednostki/s*/ @@ -907,7 +905,7 @@ public: double eAngle = 1.5; /*-dla wagonow*/ - long Load = 0.0; /*masa w T lub ilosc w sztukach - zaladowane*/ + double Load = 0.0; /*masa w T lub ilosc w sztukach - zaladowane*/ std::string LoadType; /*co jest zaladowane*/ int LoadStatus = 0; //+1=trwa rozladunek,+2=trwa zaladunek,+4=zakończono,0=zaktualizowany model double LastLoadChangeTime = 0.0; //raz (roz)ładowania @@ -1066,8 +1064,8 @@ public: bool FuseOn(void); //bezpiecznik nadamiary bool FuseFlagCheck(void); // sprawdzanie flagi nadmiarowego void FuseOff(void); // wylaczenie nadmiarowego - int ShowCurrent(int AmpN); //pokazuje bezwgl. wartosc pradu na wybranym amperomierzu - int ShowCurrentP(int AmpN); //pokazuje bezwgl. wartosc pradu w wybranym pojezdzie //Q 20160722 + double ShowCurrent( int AmpN ); //pokazuje bezwgl. wartosc pradu na wybranym amperomierzu + double ShowCurrentP(int AmpN); //pokazuje bezwgl. wartosc pradu w wybranym pojezdzie //Q 20160722 /*!o pokazuje bezwgl. wartosc obrotow na obrotomierzu jednego z 3 pojazdow*/ /*function ShowEngineRotation(VehN:int): integer; //Ra 2014-06: przeniesione do C++*/ @@ -1107,27 +1105,46 @@ public: /*funkcje ladujace pliki opisujace pojazd*/ bool LoadFIZ(std::string chkpath); //Q 20160717 bool LoadChkFile(std::string chkpath); - bool LoadFIZ_Doors( std::string const &line ); - void LoadFIZ_BuffCoupl( std::string const &line, int const Index ); + bool CheckLocomotiveParameters( bool ReadyFlag, int Dir ); + std::string EngineDescription( int what ); +private: void LoadFIZ_Param( std::string const &line ); + void LoadFIZ_Load( std::string const &line ); + void LoadFIZ_Dimensions( std::string const &line ); + void LoadFIZ_Wheels( std::string const &line ); + void LoadFIZ_Brake( std::string const &line ); + void LoadFIZ_Doors( std::string const &line ); + void LoadFIZ_BuffCoupl( std::string const &line, int const Index ); + void LoadFIZ_TurboPos( std::string const &line ); + void LoadFIZ_Cntrl( std::string const &line ); + void LoadFIZ_Light( std::string const &line ); + void LoadFIZ_Security( std::string const &line ); + void LoadFIZ_Clima( std::string const &line ); + void LoadFIZ_Power( std::string const &Line ); + void LoadFIZ_Engine( std::string const &Input ); + void LoadFIZ_Switches( std::string const &Input ); + void LoadFIZ_MotorParamTable( std::string const &Input ); + void LoadFIZ_Circuit( std::string const &Input ); + void LoadFIZ_RList( std::string const &Input ); + void LoadFIZ_DList( std::string const &Input ); + void LoadFIZ_LightsList( std::string const &Input ); + void LoadFIZ_PowerParamsDecode( TPowerParameters &Powerparameters, std::string const Prefix, std::string const &Input ); + TPowerType LoadFIZ_PowerDecode( std::string const &Power ); + TPowerSource LoadFIZ_SourceDecode( std::string const &Source ); + TEngineTypes LoadFIZ_EngineDecode( std::string const &Engine ); bool readMPT0( std::string const &line ); bool readMPT( std::string const &line ); //Q 20160717 bool readMPTElectricSeries( std::string const &line ); bool readMPTDieselElectric( std::string const &line ); bool readMPTDieselEngine( std::string const &line ); - bool readRList(int const ln, std::string const &line); //Q 20160718 bool readBPT(/*int const ln,*/ std::string const &line); //Q 20160721 + bool readRList( std::string const &Input ); bool readDList( std::string const &line ); bool readFFList( std::string const &line ); bool readWWList( std::string const &line ); - void BrakeValveDecode( std::string s ); //Q 20160719 + bool readLightsList( std::string const &Input ); + void BrakeValveDecode( std::string const &s ); //Q 20160719 void BrakeSubsystemDecode(); //Q 20160719 - void PowerParamDecode(std::string lines, std::string prefix, TPowerParameters &PowerParamDecode); //Q 20160719 - TPowerSource PowerSourceDecode(std::string s); //Q 20160719 - TPowerType PowerDecode(std::string s); //Q 20160719 - TEngineTypes EngineDecode(std::string s); //Q 20160721 - bool CheckLocomotiveParameters(bool ReadyFlag, int Dir); - std::string EngineDescription(int what); }; extern double Distance(TLocation Loc1, TLocation Loc2, TDimension Dim1, TDimension Dim2); @@ -1135,16 +1152,7 @@ extern double Distance(TLocation Loc1, TLocation Loc2, TDimension Dim1, TDimensi template bool getkeyval( _Type &Variable, std::string const &Key, std::string const &Input, std::string const &Default ) { - std::string value; - auto lookup = Input.find( Key + "=" ); - if( lookup != std::string::npos ) { - value = Input.substr( Input.find_first_not_of( ' ', lookup + Key.size() + 1 ) ); - lookup = value.find( ' ' ); - if( lookup != std::string::npos ) { - // trim everything past the value - value.erase( lookup ); - } - } + auto value = extract_value( Key, Input ); if( false == value.empty() ) { // set the specified variable to retrieved value std::stringstream converter; @@ -1161,4 +1169,21 @@ bool getkeyval( _Type &Variable, std::string const &Key, std::string const &Inpu } return false; // supplied the default } +} + +inline +std::string +extract_value( std::string const &Key, std::string const &Input ) { + + std::string value; + auto lookup = Input.find( Key + "=" ); + if( lookup != std::string::npos ) { + value = Input.substr( Input.find_first_not_of( ' ', lookup + Key.size() + 1 ) ); + lookup = value.find( ' ' ); + if( lookup != std::string::npos ) { + // trim everything past the value + value.erase( lookup ); + } + } + return value; } \ No newline at end of file diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 88809927..d83a1321 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -29,7 +29,7 @@ inline long Trunc(float f) inline long ROUND(float f) { - return Trunc(f + 0.5); + return Trunc(f + 0.5f); } inline double sqr(double val) // SQR() zle liczylo w current() ... @@ -82,7 +82,7 @@ double TMoverParameters::current(double n, double U) // w zaleznosci od polozenia nastawnikow MainCtrl i ScndCtrl oraz predkosci obrotowej n // a takze wywala bezpiecznik nadmiarowy gdy za duzy prad lub za male napiecie // jest takze mozliwosc uszkodzenia silnika wskutek nietypowych parametrow - const float ep09resED = 5.8; // TODO: dobrac tak aby sie zgadzalo ze wbudzeniem + double const ep09resED = 5.8; // TODO: dobrac tak aby sie zgadzalo ze wbudzeniem double R, MotorCurrent; double Rz, Delta, Isf; @@ -393,8 +393,8 @@ Name( NameInit ) SecuritySystem.SystemTimer = 0.0; SecuritySystem.SystemBrakeCATimer = 0.0; SecuritySystem.SystemBrakeSHPTimer = 0.0; // hunter-091012 - SecuritySystem.VelocityAllowed = -1.0; - SecuritySystem.NextVelocityAllowed = -1.0; + SecuritySystem.VelocityAllowed = -1; + SecuritySystem.NextVelocityAllowed = -1; SecuritySystem.RadioStop = false; // domyślnie nie ma SecuritySystem.AwareMinSpeed = 0.1 * Vmax; s_CAtestebrake = false; @@ -577,7 +577,7 @@ void TMoverParameters::BrakeLevelSet(double b) fBrakeCtrlPos = Handle->GetPos(bh_MIN); // odcięcie else if (fBrakeCtrlPos > Handle->GetPos(bh_MAX)) fBrakeCtrlPos = Handle->GetPos(bh_MAX); - int x = floor(fBrakeCtrlPos); // jeśli odwołujemy się do BrakeCtrlPos w pośrednich, to musi być + int x = static_cast(std::floor(fBrakeCtrlPos)); // jeśli odwołujemy się do BrakeCtrlPos w pośrednich, to musi być // obcięte a nie zaokrągone while ((x > BrakeCtrlPos) && (BrakeCtrlPos < BrakeCtrlPosNo)) // jeśli zwiększyło się o 1 if (!IncBrakeLevelOld()) // T_MoverParameters:: @@ -669,15 +669,15 @@ bool TMoverParameters::ChangeCab(int direction) bool TMoverParameters::CurrentSwitch(int direction) { // rozruch wysoki (true) albo niski (false) // Ra: przeniosłem z Train.cpp, nie wiem czy ma to sens - if (MaxCurrentSwitch(direction)) + if (MaxCurrentSwitch(direction != 0)) { if (TrainType != dt_EZT) - return (MinCurrentSwitch(direction)); + return (MinCurrentSwitch(direction != 0)); } if (EngineType == DieselEngine) // dla 2Ls150 if (ShuntModeAllow) if (ActiveDir == 0) // przed ustawieniem kierunku - ShuntMode = direction; + ShuntMode = ( direction != 0 ); return false; }; @@ -1010,7 +1010,7 @@ void TMoverParameters::CollisionDetect(int CouplerN, double dt) if (SetFlag(DamageFlag, dtrain_coupling)) EventFlag = true; - if ((coupler.CouplingFlag & ctrain_pneumatic > 0)) + if ((coupler.CouplingFlag & ctrain_pneumatic) == ctrain_pneumatic) EmergencyBrakeFlag = true; // hamowanie nagle - zerwanie przewodow hamulcowych coupler.CouplingFlag = 0; @@ -1446,7 +1446,7 @@ void TMoverParameters::ConverterCheck() ConverterFlag = false; }; -int TMoverParameters::ShowCurrent(int AmpN) +double TMoverParameters::ShowCurrent(int AmpN) { // Odczyt poboru prądu na podanym amperomierzu switch (EngineType) { @@ -1813,7 +1813,7 @@ bool TMoverParameters::IncScndCtrl(int CtrlSpeed) if ((OK) && (EngineType == ElectricInductionMotor)) if ((Vmax < 250)) - ScndCtrlActualPos = Round(Vel + 0.5); + ScndCtrlActualPos = Round(Vel + 0.5f); else ScndCtrlActualPos = Round(Vel * 1.0 / 2 + 0.5); @@ -2426,6 +2426,7 @@ bool TMoverParameters::IncLocalBrakeLevel(int CtrlSpeed) while ((LocalBrakePos < LocalBrakePosNo) && (CtrlSpeed > 0)) { LocalBrakePos++; +// LocalBrakePosA = static_cast(LocalBrakePos) / LocalBrakePosNo; // temporary hack until i figure out how this element is supposed to work CtrlSpeed--; } IBL = true; @@ -2449,6 +2450,7 @@ bool TMoverParameters::DecLocalBrakeLevel(int CtrlSpeed) while ((CtrlSpeed > 0) && (LocalBrakePos > 0)) { LocalBrakePos--; +// LocalBrakePosA = static_cast( LocalBrakePos ) / LocalBrakePosNo; // temporary hack until i figure out how this element is supposed to work CtrlSpeed--; } DBL = true; @@ -2470,6 +2472,7 @@ bool TMoverParameters::IncLocalBrakeLevelFAST(void) if (LocalBrakePos < LocalBrakePosNo) { LocalBrakePos = LocalBrakePosNo; +// LocalBrakePosA = static_cast( LocalBrakePos ) / LocalBrakePosNo; // temporary hack until i figure out how this element is supposed to work ILBLF = true; } else @@ -2488,6 +2491,7 @@ bool TMoverParameters::DecLocalBrakeLevelFAST(void) if (LocalBrakePos > 0) { LocalBrakePos = 0; +// LocalBrakePosA = static_cast( LocalBrakePos ) / LocalBrakePosNo; // temporary hack until i figure out how this element is supposed to work DLBLF = true; } else @@ -2937,10 +2941,10 @@ void TMoverParameters::UpdatePipePressure(double dt) { const double LBDelay = 100; const double kL = 0.5; - double dV; - TMoverParameters *c; // T_MoverParameters + //double dV; + //TMoverParameters *c; // T_MoverParameters double temp; - int b; + //int b; PipePress = Pipe->P(); // PPP:=PipePress; @@ -2952,7 +2956,7 @@ void TMoverParameters::UpdatePipePressure(double dt) { if ((EngineType != ElectricInductionMotor)) dpLocalValve = - LocHandle->GetPF(Max0R(LocalBrakePos / LocalBrakePosNo, LocalBrakePosA), + LocHandle->GetPF(std::max(static_cast(LocalBrakePos) / LocalBrakePosNo, LocalBrakePosA), Hamulec->GetBCP(), ScndPipePress, dt, 0); else dpLocalValve = @@ -3210,7 +3214,7 @@ double TMoverParameters::GetDVc(double dt) { // T_MoverParameters *c; TMoverParameters *c; - double dv1, dv2, dV; + double dv1, dv2;// , dV; dv1 = 0; dv2 = 0; @@ -3382,16 +3386,18 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer) else FTrain = 0; Fb = BrakeForce(RunningTrack); - if (Max0R(abs(FTrain), Fb) > TotalMassxg * Adhesive(RunningTrack.friction)) // poslizg + if( std::max( std::abs( FTrain ), Fb ) > TotalMassxg * Adhesive( RunningTrack.friction ) ) // poslizg { SlippingWheels = true; + } + if( true == SlippingWheels ) { // TrainForce:=TrainForce-Fb; nrot = ComputeRotatingWheel((FTrain - Fb * Sign(V) - FStand) / NAxles - - Sign(nrot * PI * WheelDiameter - V) * + Sign(nrot * M_PI * WheelDiameter - V) * Adhesive(RunningTrack.friction) * TotalMass, dt, nrot); FTrain = Sign(FTrain) * TotalMassxg * Adhesive(RunningTrack.friction); - Fb = Min0R(Fb, TotalMassxg * Adhesive(RunningTrack.friction)); + Fb = std::min(Fb, TotalMassxg * Adhesive(RunningTrack.friction)); } // else SlippingWheels:=false; // FStand:=0; @@ -3513,7 +3519,7 @@ double TMoverParameters::BrakeForce(const TTrackParam &Track) // Fb:=UnitBrakeForce*NBpA {ham. reczny dziala na jedna os} // else //yB: to nie do konca ma sens, ponieważ ręczny w wagonie działa na jeden cylinder // hamulcowy/wózek, dlatego potrzebne są oddzielnie liczone osie - Fb = UnitBrakeForce * NBrakeAxles * Max0R(1, NBpA); + Fb = UnitBrakeForce * NBrakeAxles * std::max(1, NBpA); // u:=((BrakePress*P2FTrans)-BrakeCylSpring*BrakeCylMult[BCMFlag]/BrakeCylNo-0.83*BrakeSlckAdj/(BrakeCylNo))*BrakeCylNo; // { end; } @@ -3541,28 +3547,41 @@ double TMoverParameters::FrictionForce(double R, int TDamage) // ************************************************************************************************* double TMoverParameters::Adhesive(double staticfriction) { - double adhesive; - + double adhesion; +/* // ABu: male przerobki, tylko czy to da jakikolwiek skutek w FPS? // w kazdym razie zaciemni kod na pewno :) if (SlippingWheels == false) { if (SandDose) - adhesive = (Max0R(staticfriction * (100.0 + Vel) / ((50.0 + Vel) * 11.0), 0.048)) * + adhesion = (Max0R(staticfriction * (100.0 + Vel) / ((50.0 + Vel) * 11.0), 0.048)) * (11.0 - 2.0 * Random(0.0, 1.0)); else - adhesive = (staticfriction * (100.0 + Vel) / ((50.0 + Vel) * 10.0)) * + adhesion = (staticfriction * (100.0 + Vel) / ((50.0 + Vel) * 10.0)) * (11.0 - 2.0 * Random(0.0, 1.0)); } else { if (SandDose) - adhesive = (0.048) * (11.0 - 2.0 * Random(0.0, 1.0)); + adhesion = (0.048) * (11.0 - 2.0 * Random(0.0, 1.0)); else - adhesive = (staticfriction * 0.02) * (11.0 - 2.0 * Random(0.0, 1.0)); + adhesion = (staticfriction * 0.02) * (11.0 - 2.0 * Random(0.0, 1.0)); } // WriteLog(FloatToStr(adhesive)); // tutaj jest na poziomie 0.2 - 0.3 - return adhesive; + return adhesion; +*/ + if( true == SlippingWheels ) { + + if( true == SandDose ) { adhesion = 0.48; } + else { adhesion = staticfriction * 0.2; } + } + else { + + if( true == SandDose ) { adhesion = std::max( staticfriction * ( 100.0 + Vel ) / ( 50.0 + Vel ) * 1.1, 0.48 ); } + else { adhesion = staticfriction * ( 100.0 + Vel ) / ( 50.0 + Vel ); } + } + adhesion *= ( 11.0 - 2 * Random() ) / 10.0; + return adhesion; } // poprawka dla liczenia sil przy ustawieniu przeciwnym obiektow: @@ -3641,7 +3660,7 @@ double TMoverParameters::CouplerForce(int CouplerN, double dt) // Connected.Couplers[CNext].Connected:=nil; //Ra: ten podłączony niekoniecznie jest // wirtualny Couplers[CouplerN].Connected = NULL; - ScanCounter = Random(500); // Q: TODO: cy dobrze przetlumaczone? + ScanCounter = static_cast(Random(500.0)); // Q: TODO: cy dobrze przetlumaczone? // WriteLog(FloatToStr(ScanCounter)); } } @@ -3786,9 +3805,9 @@ double TMoverParameters::TractionForce(double dt) } eAngle += enrot * dt; - if (eAngle > Pirazy2) + while (eAngle > M_PI * 2.0) // eAngle = Pirazy2 - eAngle; <- ABu: a nie czasem tak, jak nizej? - eAngle -= Pirazy2; + eAngle -= M_PI * 2.0; // hunter-091012: przeniesione z if ActiveDir<>0 (zeby po zejsciu z kierunku dalej spadala // predkosc wentylatorow) @@ -4177,17 +4196,17 @@ double TMoverParameters::TractionForce(double dt) } else PosRatio = 0; - PosRatio = (double)Round(20 * PosRatio) / 20; - if (PosRatio < 19.5 / 20) + PosRatio = Round(20.0 * PosRatio) / 20.0; + if (PosRatio < 19.5 / 20.0) PosRatio *= 0.9; // if PosRatio<0 then // PosRatio:=2+PosRatio-2; - Hamulec->SetED(Max0R(0.0, Min0R(PosRatio, 1))); + Hamulec->SetED(Max0R(0.0, std::min(PosRatio, 1.0))); // (Hamulec as TLSt).SetLBP(LocBrakePress*(1-PosRatio)); - PosRatio = -Max0R(Min0R(dtrans * 1.0 / MaxBrakePress[0], 1), AnPos) * - Max0R(0, Min0R(1, (Vel - eimc[eimc_p_Vh0]) / + PosRatio = -std::max(std::min(dtrans * 1.0 / MaxBrakePress[0], 1.0), AnPos) * + std::max(0.0, std::min(1.0, (Vel - eimc[eimc_p_Vh0]) / (eimc[eimc_p_Vh1] - eimc[eimc_p_Vh0]))); - eimv[eimv_Fzad] = -Max0R(LocalBrakeRatio(), dtrans / MaxBrakePress[0]); + eimv[eimv_Fzad] = -std::max(LocalBrakeRatio(), dtrans / MaxBrakePress[0]); tmp = 5; } else @@ -4454,10 +4473,10 @@ double TMoverParameters::v2n(void) const double dmgn = 0.5; double n, deltan = 0; - n = V / (PI * WheelDiameter); // predkosc obrotowa wynikajaca z liniowej [obr/s] + n = V / (M_PI * WheelDiameter); // predkosc obrotowa wynikajaca z liniowej [obr/s] deltan = n - nrot; //"pochodna" prędkości obrotowej if (SlippingWheels) - if (abs(deltan) < 0.01) + if (std::abs(deltan) < 0.01) SlippingWheels = false; // wygaszenie poslizgu if (SlippingWheels) // nie ma zwiazku z predkoscia liniowa V { // McZapkie-221103: uszkodzenia kol podczas poslizgu @@ -5428,7 +5447,7 @@ double TMoverParameters::GetTrainsetVoltage(void) // ************************************************************************************************* bool TMoverParameters::Physic_ReActivation(void) // DO PRZETLUMACZENIA NA KONCU { - bool pr; +// bool pr; if (PhysicActivation) return false; else @@ -5443,7 +5462,6 @@ bool TMoverParameters::Physic_ReActivation(void) // DO PRZETLUMACZENIA NA KONCU // FUNKCJE PARSERA WCZYTYWANIA PLIKU FIZYKI POJAZDU // ************************************************************************************************* std::string p0, p1, p2, p3, p4, p5, p6, p7; -std::string xline, sectionname, lastsectionname; std::string vS; int vI; double vD; @@ -5451,83 +5469,10 @@ bool startBPT; bool startMPT, startMPT0; bool startRLIST; bool startDLIST, startFFLIST, startWWLIST; -int MPTLINE, RLISTLINE, BPTLINE, DLISTLINE, FFLISTLINE, WWLISTLINE; +bool startLIGHTSLIST; +int LISTLINE; std::vector x; -std::string aCategory, aType; -double aMass, aMred, aVmax, aPWR, aHeatingP, aLightP; -int aSandCap; - -std::string bLoadQ, bLoadAccepted; -double bLoadSpeed, bUnLoadSpeed, bOverLoadFactor, cL, cW, cH, cCx, cFloor; -int bMaxLoad; - -std::string dAxle, dBearingType; -double dD, dDl, dDt, dAIM, dTw, dAd, dBd, dRmin; - -std::string eBrakeValve, eBM, eCompressorPower; -double eMBF, eTBF, eMaxBP, eMedMaxBP, eTareMaxBP, eMaxLBP, eMaxASBP, eRM, eBCR, eBCD, eBCM, eBCMlo, - eBCMhi, eVv, eMinCP, eMaxCP, eBCS, eBSA, eBRE, eHiPP, eLoPP, eCompressorSpeed; -int eNBpA, eBVV, eBCN, eSize; - -std::string fCType; -double fkB, fDmaxB, fFmaxB, fkC, fDmaxC, fFmaxC, fbeta; -int fAllowedFlag; - -std::string gBrakeSystem, gASB, gLocalBrake, gDynamicBrake, gManualBrake, gScndS, gFSCircuit, - gAutoRelay, gBrakeDelays, gBrakeHandle, gLocBrakeHandle, gCoupledCtrl; -float gIniCDelay, gSCDelay, gSCDDelay, gMaxBPMass; -int gBCPN, gBDelay1, gBDelay2, gBDelay3, gBDelay4, gMCPN, gSCPN, gSCIM; - -std::string hAwareSystem, hRadioStop; -double hAwareMinSpeed, hAwareDelay, hSoundSignalDelay, hEmergencyBrakeDelay; - -std::string iLight, iLGeneratorEngine; -double iLMaxVoltage, iLMaxCurrent; - -std::string jEnginePower, jSystemPower; -double jMaxVoltage, jMaxCurrent, jIntR, jMinH, jMaxH, jCSW, jMinV, jMaxV, jMinPress, jMaxPress; -int jCollectorsNo; - -std::string kEngineType, kTrans; -double kVolt, kWindingRes, kNMin, kNMax, kNMaxCutoff, kAIM, kshuntmode; -// int kVolt; -// motorparamtable -double kMinVelFullEngage, kEngageDia, kEngageMaxForce, kEngageFriction; - -double lCircuitRes; -int lImaxLo, lImaxHi, lIminLo, lIminHi; - -std::string mRVent; -double mRVentnmax, mRVentCutOff; -int mSize; - -double nMmax, nnMmax, nMnmax, nnmax, nnominalfill, nMstand; -int nSize; - -/*inline int ti(std::string val) -{ - return atoi(val.c_str()); -} - -inline double td(std::string val) -{ - return atof(val.c_str()); -} - -std::string ts(std::string val) -{ - // WriteLog("["+ val + "]"); - - return val; - // else return "unknown"; -} - -std::string tS(std::string val) -{ - return ToUpper(val); -}*/ - // ************************************************************************************************* // Q: 20160717 // ************************************************************************************************* @@ -5536,7 +5481,7 @@ int Pos(std::string str_find, std::string in) size_t pos = in.find(str_find); return (pos != std::string::npos ? pos+1 : 0); } - +/* // ************************************************************************************************* // Q: 20160717 // ************************************************************************************************* @@ -5551,46 +5496,10 @@ bool issection(std::string const &name) else return false; } +*/ +bool issection( std::string const &Name, std::string const &Input ) { -// ************************************************************************************************* -// Q: 20160717 -// ************************************************************************************************* -// Pobieranie wartosci z klucza i przypisanie jej do wlasciwego typu danych 1 - string, 2 - int, 3 - -// double -std::string getkeyval(int rettype, std::string key) -{ - std::string keyname = key; - key = key + "="; - std::string kval, temp; - temp = xline; - int to; - - if (Pos(key, xline) > 0) // jezeli jest klucz w swkcji... - { - int klen = key.length(); - int kpos = Pos(key, xline) - 1; - temp.erase(0, kpos + klen); - if (temp.find(' ') != std::string::npos) - to = temp.find(' '); - else - to = 255; - kval = temp.substr(0, to); - if (kval != "") - kval = TrimSpace(kval); // wyciagnieta wartosc - - sectionname = ExchangeCharInString(sectionname, ':', NULL); - sectionname = ExchangeCharInString(sectionname, '.', NULL); - //--WriteLog(sectionname + "." + keyname + " val= [" + kval + "]"); - - // if (rettype == 1) vS = kval; - // if (kval != "" && rettype == 2) vI = StrToInt(kval); - // if (kval != "" && rettype == 3) vD = StrToFloat(kval); - } - else - kval = ""; // gdy nie bylo klucza TODO: dodac do funkcji parametr z wartoscia fabryczna - // UWAGA! 0 moze powodowac bledy, przemyslec zwracanie wartosci gdy nie ma klucza!!! - // zwraca pusty klucz GF 2016-10-26 - return kval; + return ( Input.compare( 0, Name.size(), Name ) == 0 ); } int MARKERROR(int code, std::string type, std::string msg) @@ -5602,9 +5511,8 @@ int MARKERROR(int code, std::string type, std::string msg) int s2NPW(std::string s) { // wylicza ilosc osi napednych z opisu ukladu osi const char A = 64; - int k; int NPW = 0; - for (k = 0; k < s.length(); k++) + for (std::size_t k = 0; k < s.size(); ++k) { if (s[k] >= (char)65 && s[k] <= (char)90) NPW += s[k] - A; @@ -5615,9 +5523,8 @@ int s2NPW(std::string s) int s2NNW(std::string s) { // wylicza ilosc osi nienapedzanych z opisu ukladu osi const char Zero = 48; - int k; int NNW = 0; - for (k = 0; k < s.length(); k++) + for (std::size_t k = 0; k < s.size(); ++k) { if (s[k] >= (char)49 && s[k] <= (char)57) NNW += s[k] - Zero; @@ -5633,7 +5540,7 @@ bool TMoverParameters::readMPT0( std::string const &line ) { cParser parser( line ); if( false == parser.getTokens( 7, false ) ) { - WriteLog( "Read MPT0: arguments missing in line " + std::to_string( MPTLINE ) ); + WriteLog( "Read MPT0: arguments missing in line " + std::to_string( LISTLINE ) ); return false; } int idx = 0; // numer pozycji @@ -5657,9 +5564,10 @@ bool TMoverParameters::readMPT0( std::string const &line ) { } bool TMoverParameters::readMPT( std::string const &line ) { - ++MPTLINE; - switch( EngineDecode( kEngineType ) ) { + ++LISTLINE; + + switch( EngineType ) { case ElectricSeriesMotor: { return readMPTElectricSeries( line ); } case DieselElectric: { return readMPTDieselElectric( line ); } @@ -5672,7 +5580,7 @@ bool TMoverParameters::readMPTElectricSeries(std::string const &line) { cParser parser( line ); if( false == parser.getTokens( 5, false ) ) { - WriteLog( "Read MPT: arguments missing in line " + std::to_string( MPTLINE ) ); + WriteLog( "Read MPT: arguments missing in line " + std::to_string( LISTLINE ) ); return false; } int idx = 0; // numer pozycji @@ -5696,7 +5604,7 @@ bool TMoverParameters::readMPTDieselElectric( std::string const &line ) { cParser parser( line ); if( false == parser.getTokens( 7, false ) ) { - WriteLog( "Read MPT: arguments missing in line " + std::to_string( MPTLINE ) ); + WriteLog( "Read MPT: arguments missing in line " + std::to_string( LISTLINE ) ); return false; } int idx = 0; // numer pozycji @@ -5716,7 +5624,7 @@ bool TMoverParameters::readMPTDieselEngine( std::string const &line ) { cParser parser( line ); if( false == parser.getTokens( 4, false ) ) { - WriteLog( "Read MPT: arguments missing in line " + std::to_string( MPTLINE ) ); + WriteLog( "Read MPT: arguments missing in line " + std::to_string( LISTLINE ) ); return false; } int idx = 0; // numer pozycji @@ -5736,70 +5644,15 @@ bool TMoverParameters::readMPTDieselEngine( std::string const &line ) { return true; } +bool TMoverParameters::readBPT( std::string const &line ) { -// ************************************************************************************************* -// Q: 20160718 -// ************************************************************************************************* -// parsowanie RList -bool TMoverParameters::readRList(int const ln, std::string const &line) -{ - startRLIST = true; - - if (ln > 0) // 0 to nazwa sekcji - RList: - { - // WriteLog("RLIST: " + xline); -/* - line = Tab2Sp(line); // zamieniamy taby na spacje (ile tabow tyle spacji bedzie) - - xxx = TrimAndReduceSpaces(line.c_str()); // konwertujemy na *char i - // ograniczamy spacje pomiedzy - // parametrami do jednej -*/ - x = Split(line); // split je wskaznik na char jak i std::string - - int s = x.size(); - if ( ( s < 5 ) - || ( s > 6 )) - { - WriteLog("Read RLIST: wrong number of arguments (" + std::to_string(s) + ") in line " + std::to_string(ln - 1)); - RLISTLINE++; - return false; - } -/* - for (int i = 0; i < s; i++) - x[i] = TrimSpace(x[i]); -*/ - int k = ln - 1; - - RlistSize = (mSize); - if (RlistSize > ResArraySize) - ConversionError = -4; - - RList[k].Relay = atoi(x[0].c_str()); // int - RList[k].R = atof(x[1].c_str()); // double - RList[k].Bn = atoi(x[2].c_str()); // int - RList[k].Mn = atoi(x[3].c_str()); // int - RList[k].AutoSwitch = (bool)atoi(x[4].c_str()); // p4.ToInt(); - RList[k].ScndAct = s == 6 ? atoi(x[5].c_str()) : 0; //jeśli ma boczniki w nastawniku - //--WriteLog("RLIST: " + p0 + "," + p1 + "," + p2 + "," + p3 + "," + p4); - } - RLISTLINE++; - return true; -} - -// ************************************************************************************************* -// Q: 20160721 -// ************************************************************************************************* -// parsowanie Brake Param Table -bool TMoverParameters::readBPT(/*int const ln,*/ std::string const &line) - { cParser parser( line ); - if( false == parser.getTokens( 5, false ) ) - { - WriteLog( "Read BPT: arguments missing in line " + std::to_string( BPTLINE + 1 ) ); + if( false == parser.getTokens( 5, false ) ) { + + WriteLog( "Read BPT: arguments missing in line " + std::to_string( LISTLINE + 1 ) ); return false; - } - ++BPTLINE; + } + ++LISTLINE; std::string braketype; int idx = 0; parser >> idx; parser @@ -5810,22 +5663,32 @@ bool TMoverParameters::readBPT(/*int const ln,*/ std::string const &line) if( braketype == "Pneumatic" ) { BrakePressureTable[ idx ].BrakeType = Pneumatic; } else if( braketype == "ElectroPneumatic" ) { BrakePressureTable[ idx ].BrakeType = ElectroPneumatic; } else { BrakePressureTable[ idx ].BrakeType = Individual; } -/* - int k = atoi( x[ 0 ].c_str() ); - BrakePressureTable[k].PipePressureVal = atof(x[1].c_str()); - BrakePressureTable[k].BrakePressureVal = atof(x[2].c_str()); - BrakePressureTable[k].FlowSpeedVal = atof(x[3].c_str()); - if (x[4] == "Pneumatic") - BrakePressureTable[k].BrakeType = Pneumatic; - else if (x[4] == "ElectroPneumatic") - BrakePressureTable[k].BrakeType = ElectroPneumatic; - else - BrakePressureTable[k].BrakeType = Individual; -*/ - // WriteLog("BPTx: " + p0 + "," + p1 + "," + p2 + "," + p3 + "," + p4); - //WriteLog("BPTk: " + to_string(k) + "," + to_string(BrakePressureTable[k].PipePressureVal) + - // "," + to_string(BrakePressureTable[k].BrakePressureVal) + "," + - // to_string(BrakePressureTable[k].FlowSpeedVal) + "," + p4); + + return true; +} + +bool TMoverParameters::readRList( std::string const &Input ) { + + cParser parser( Input ); + if( false == parser.getTokens( 5, false ) ) { + + WriteLog( "Read RList: arguments missing in line " + std::to_string( LISTLINE + 1 ) ); + return false; + } + auto idx = LISTLINE++; + if( idx >= sizeof( RList ) ) { + WriteLog( "Read RList: number of entries exceeded capacity of the data table" ); + return false; + } + parser + >> RList[ idx ].Relay + >> RList[ idx ].R + >> RList[ idx ].Bn + >> RList[ idx ].Mn + >> RList[ idx ].AutoSwitch; + + if( true == parser.getTokens( 1, false ) ) { parser >> RList[ idx ].ScndAct; } + else { RList[ idx ].ScndAct = 0; } return true; } @@ -5834,7 +5697,7 @@ bool TMoverParameters::readDList( std::string const &line ) { cParser parser( line ); parser.getTokens( 3, false ); - auto idx = DLISTLINE++; + auto idx = LISTLINE++; if( idx >= sizeof( RList ) ) { WriteLog( "Read DList: number of entries exceeded capacity of the data table" ); return false; @@ -5851,10 +5714,10 @@ bool TMoverParameters::readFFList( std::string const &line ) { cParser parser( line ); if( false == parser.getTokens( 2, false ) ) { - WriteLog( "Read FList: arguments missing in line " + std::to_string( FFLISTLINE + 1 ) ); + WriteLog( "Read FList: arguments missing in line " + std::to_string( LISTLINE + 1 ) ); return false; } - int idx = FFLISTLINE++; + int idx = LISTLINE++; if( idx >= sizeof( DElist ) ) { WriteLog( "Read FList: number of entries exceeded capacity of the data table" ); return false; @@ -5871,10 +5734,10 @@ bool TMoverParameters::readWWList( std::string const &line ) { cParser parser( line ); if( false == parser.getTokens( 4, false ) ) { - WriteLog( "Read WWList: arguments missing in line " + std::to_string( WWLISTLINE + 1 ) ); + WriteLog( "Read WWList: arguments missing in line " + std::to_string( LISTLINE + 1 ) ); return false; } - int idx = WWLISTLINE++; + int idx = LISTLINE++; if( idx >= sizeof( DElist ) ) { WriteLog( "Read WWList: number of entries exceeded capacity of the data table" ); return false; @@ -5899,51 +5762,71 @@ bool TMoverParameters::readWWList( std::string const &line ) { return true; } +bool TMoverParameters::readLightsList( std::string const &Input ) { + + cParser parser( Input ); + if( false == parser.getTokens( 2, false ) ) { + WriteLog( "Read LightsList: arguments missing in line " + std::to_string( LISTLINE + 1 ) ); + return false; + } + int idx = LISTLINE++; + if( idx > 16 ) { + WriteLog( "Read LightsList: number of entries exceeded capacity of the data table" ); + return false; + } + parser + >> Lights[ 0 ][ idx ] + >> Lights[ 1 ][ idx ]; + + return true; +} + // ************************************************************************************************* // Q: 20160719 // ************************************************************************************************* -void TMoverParameters::BrakeValveDecode(std::string s) -{ - if (s == "W") - BrakeValve = W; - else if (s == "W_Lu_L") - BrakeValve = W_Lu_L; - else if (s == "W_Lu_XR") - BrakeValve = W_Lu_XR; - else if (s == "W_Lu_VI") - BrakeValve = W_Lu_VI; - else if (s == "K") - BrakeValve = W; - else if (s == "Kkg") - BrakeValve = Kkg; - else if (s == "Kkp") - BrakeValve = Kkp; - else if (s == "Kks") - BrakeValve = Kks; - else if (s == "Hikp1") - BrakeValve = Hikp1; - else if (s == "Hikss") - BrakeValve = Hikss; - else if (s == "Hikg1") - BrakeValve = Hikg1; - else if (s == "KE") - BrakeValve = KE; - else if (s == "EStED") - BrakeValve = EStED; - else if (Pos("ESt", s) > 0) +void TMoverParameters::BrakeValveDecode( std::string const &Valve ) { + + std::map valvetypes{ + { "W", W }, + { "W_Lu_L", W_Lu_L }, + { "W_Lu_XR", W_Lu_XR }, + { "W_Lu_VI", W_Lu_VI }, + { "K", K }, + { "Kg", Kg }, + { "Kp", Kp }, + { "Kss", Kss }, + { "Kkg", Kkg }, + { "Kkp", Kkp }, + { "Kks", Kks }, + { "Hikp1", Hikp1 }, + { "Hikss", Hikss }, + { "Hikg1", Hikg1 }, + { "KE", KE }, + { "SW", SW }, + { "EStED", EStED }, + { "NESt3", NESt3 }, + { "ESt3", ESt3 }, + { "LSt", LSt }, + { "ESt4", ESt4 }, + { "ESt3AL2", ESt3AL2 }, + { "EP1", EP1 }, + { "EP2", EP2 }, + { "M483", M483 }, + { "CV1_L_TR", CV1_L_TR }, + { "CV1", CV1 }, + { "CV1_R", CV1_R } + }; + auto lookup = valvetypes.find( Valve ); + BrakeValve = + lookup != valvetypes.end() ? + lookup->second : + Other; + + if( ( BrakeValve == Other ) + && ( Valve.find( "ESt" ) != std::string::npos ) ) { + BrakeValve = ESt3; - else if (s == "LSt") - BrakeValve = LSt; - else if (s == "EP2") - BrakeValve = EP2; - else if (s == "EP1") - BrakeValve = EP1; - else if (s == "CV1") - BrakeValve = CV1; - else if (s == "CV1_L_TR") - BrakeValve = CV1_L_TR; - else - BrakeValve = Other; + } } // ************************************************************************************************* @@ -5981,155 +5864,6 @@ void TMoverParameters::BrakeSubsystemDecode() } } -// ************************************************************************************************* -// Q: 20160721 -// ************************************************************************************************* -TEngineTypes TMoverParameters::EngineDecode(std::string s) -{ - if (s == "ElectricSeriesMotor") - return ElectricSeriesMotor; - else if (s == "DieselEngine") - return DieselEngine; - else if (s == "SteamEngine") - return SteamEngine; - else if (s == "WheelsDriven") - return WheelsDriven; - else if (s == "Dumb") - return Dumb; - else if (s == "DieselElectric") - return DieselElectric; - else // youBy: spal-ele - if (s == "DumbDE") - return DieselElectric; - else // youBy: spal-ele - if (s == "ElectricInductionMotor") - return ElectricInductionMotor; - // else if s='EZT' then {dla kibla} - // EngineDecode:=EZT } - else - return None; -} - -// ************************************************************************************************* -// Q: 20160719 -// ************************************************************************************************* -TPowerSource TMoverParameters::PowerSourceDecode(std::string s) -{ - - if (s == "Transducer") - return Transducer; - else if (s == "Generator") - return Generator; - else if (s == "Accu") - return Accumulator; - else if (s == "CurrentCollector") - return CurrentCollector; - else if (s == "PowerCable") - return PowerCable; - else if (s == "Heater") - return Heater; - else if (s == "Internal") - return InternalSource; - else - return NotDefined; -} - -// ************************************************************************************************* -// Q: 20160719 -// ************************************************************************************************* -TPowerType TMoverParameters::PowerDecode(std::string s) -{ - if (s == "BioPower") - return BioPower; - else if (s == "MechPower") - return MechPower; - else if (s == "ElectricPower") - return ElectricPower; - else if (s == "SteamPower") - return SteamPower; - else - return NoPower; -} - -// ************************************************************************************************* -// Q: 20160719 -// ************************************************************************************************* -void TMoverParameters::PowerParamDecode(std::string lines, std::string prefix, - TPowerParameters &PowerParamDecode) -{ - // with PowerParamDecode do - // begin - switch (PowerParamDecode.SourceType) - { - //--case NotDefined : PowerType = PowerDecode(DUE(ExtractKeyWord(lines,prefix+'PowerType='))); - //--case InternalSource : PowerType = - //PowerDecode(DUE(ExtractKeyWord(lines,prefix+'PowerType='))); - //--case Transducer : InputVoltage = - //s2rE(DUE(ExtractKeyWord(lines,prefix+'TransducerInputV='))); - //--case Generator : - //GeneratorEngine:=EngineDecode(DUE(ExtractKeyWord(lines,prefix+'GeneratorEngine='))); - //--case Accumulator: - //--{ - //-- RAccumulator.MaxCapacity:=s2r(DUE(ExtractKeyWord(lines,prefix+'Cap='))); - //-- s:=DUE(ExtractKeyWord(lines,prefix+'RS=')); - //-- RAccumulator.RechargeSource:=PowerSourceDecode(s); - //--} - - case CurrentCollector: - { - - PowerParamDecode.CollectorParameters.CollectorsNo = (jCollectorsNo); - PowerParamDecode.CollectorParameters.MinH = (jMinH); - PowerParamDecode.CollectorParameters.MaxH = (jMaxH); - PowerParamDecode.CollectorParameters.CSW = (jCSW); // szerokość części roboczej - PowerParamDecode.CollectorParameters.MaxV = (jMaxVoltage); - - // s:=jMinV; //napięcie rozłączające WS - if (jMinV == 0) - PowerParamDecode.CollectorParameters.MinV = - 0.5 * PowerParamDecode.CollectorParameters.MaxV; // gdyby parametr nie podany - else - PowerParamDecode.CollectorParameters.MinV = (jMinV); - - //-s:=ExtractKeyWord(lines,'InsetV='); //napięcie wymagane do załączenia WS - //-if s='' then - //- InsetV:=0.6*MaxV //gdyby parametr nie podany - //-else - //- InsetV:=s2rE(DUE(s)); - // s:=ExtractKeyWord(lines,'MinPress='); //ciśnienie rozłączające WS - if (jMinPress == 0) - PowerParamDecode.CollectorParameters.MinPress = 2.0; // domyślnie 2 bary do załączenia - // WS - else - PowerParamDecode.CollectorParameters.MinPress = (jMinPress); - // s:=ExtractKeyWord(lines,'MaxPress='); //maksymalne ciśnienie za reduktorem - if (jMaxPress == 0) - PowerParamDecode.CollectorParameters.MaxPress = 5.0 + 0.001 * (Random(50) - Random(50)); - else - PowerParamDecode.CollectorParameters.MaxPress = (jMaxPress); - } - // case PowerCable: - //{ - // RPowerCable.PowerTrans:=PowerDecode(DUE(ExtractKeyWord(lines,prefix+'PowerTrans='))); - // if RPowerCable.PowerTrans=SteamPower then - // RPowerCable.SteamPressure:=s2r(DUE(ExtractKeyWord(lines,prefix+'SteamPress='))); - //} - // case Heater : - //{ - // //jeszcze nie skonczone! - //} - } - - if ((PowerParamDecode.SourceType != Heater) && (PowerParamDecode.SourceType != InternalSource)) - if (!((PowerParamDecode.SourceType == PowerCable) && - (PowerParamDecode.RPowerCable.PowerTrans == SteamPower))) - { - //--MaxVoltage =s2rE(DUE(ExtractKeyWord(lines,prefix+'MaxVoltage='))); - //--MaxCurrent =s2r(DUE(ExtractKeyWord(lines,prefix+'MaxCurrent='))); - //--IntR =s2r(DUE(ExtractKeyWord(lines,prefix+'IntR='))); - } -} - // ************************************************************************************************* // Q: 20160717 // Funkcja pelniaca role pierwotnej LoadChkFile wywolywana w dynobj.cpp w double @@ -6142,41 +5876,20 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) const int wheels_ok = 2; const int dimensions_ok = 4; - int ishash; - int bl, i, k; - int b, OKFlag; - std::string lines, s, appdir; - std::string APPDIR, filetocheck, line, node, key, file, CERR; - std::string wers; - bool noexist = false; - bool OK; - - OKFlag = 0; - LineCount = 0; ConversionError = 666; + LISTLINE = 0; startBPT = false; - BPTLINE = 0; startMPT = false; startMPT0 = false; - MPTLINE = 0; startRLIST = false; - RLISTLINE = 0; startDLIST = false; startFFLIST = false; startWWLIST = false; - WWLISTLINE = 0; - DLISTLINE = 0; - FFLISTLINE = 0; - Mass = 0; - file = chkpath + TypeName + ".fiz"; + startLIGHTSLIST = false; + std::string file = chkpath + TypeName + ".fiz"; WriteLog("LOAD FIZ FROM " + file); - // if (!FileExists(file)) WriteLog("E8 - FIZ FILE NOT EXIST."); - // if (!FileExists(file)) return false; - - // appdir = ExtractFilePath(ParamStr(0)); - std::ifstream in(file); if (!in.is_open()) { @@ -6184,1048 +5897,313 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) return false; } - bool secBPT = false, secMotorParamTable = false, secPower = false, secEngine = false, - secParam = false, secLoad = false, secDimensions = false, - secWheels = false, secBrake = false, secBuffCoupl = false, secCntrl = false, - secSecurity = false, secLight = false, secCircuit = false, secRList = false, - secDList = false, secWWList = false, secffList = false, secTurboPos = false; - ConversionError = 0; // Zbieranie danych zawartych w pliku FIZ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - while (std::getline(in, wers)) + std::unordered_map fizlines; + std::string inputline; + while (std::getline(in, inputline)) { - // wers.find('#'); - xline = wers; - bool comment = ( ( xline.find('#') != std::string::npos ) - || ( xline.compare( 0, 2, "//" ) == 0 ) ); - // if ((ishash == 1)) WriteLog("zakomentowane " + xline); - if( false == comment ) + bool comment = ( ( inputline.find('#') != std::string::npos ) + || ( inputline.compare( 0, 2, "//" ) == 0 ) ); + if( true == comment ) { + // skip commented lines + continue; + } + + if( inputline.length() == 0 ) { + startBPT = false; + continue; + } + // checking if table parsing should be switched off goes first... + if( issection( "END-MPT", inputline ) ) { + startBPT = false; + startMPT = false; + startMPT0 = false; + continue; + } + if( issection( "END-RL", inputline ) ) { + startBPT = false; + startRLIST = false; + continue; + } + if( issection( "END-DL", inputline ) ) { + startBPT = false; + startDLIST = false; + continue; + } + if( issection( "endff", inputline ) ) { + startBPT = false; + startFFLIST = false; + continue; + } + if( issection( "END-WWL", inputline ) ) { + startBPT = false; + startWWLIST = false; + continue; + } + if( issection( "endL", inputline ) ) { + startBPT = false; + startLIGHTSLIST = false; + continue; + } + // ...then all recognized sections... + if( issection( "Param.", inputline ) ) { - if( xline.length() == 0 ) { - startBPT = false; - continue; - } - // checking if table parsing should be switched off goes first... - if( issection( "END-MPT" ) ) { - startBPT = false; - startMPT = false; - startMPT0 = false; - continue; - } - if( issection( "END-RL" ) ) { - startBPT = false; - startRLIST = false; - continue; - } - if( issection( "END-DL" ) ) { - startBPT = false; - startDLIST = false; - continue; - } - if( issection( "endff" ) ) { - startBPT = false; - startFFLIST = false; - continue; - } - if( issection( "END-WWL" ) ) { - startBPT = false; - startWWLIST = false; - continue; - } - // ...then all recognized sections... - if (issection("Param.")) - { - startBPT = false; - secParam = true; - SetFlag( OKFlag, param_ok ); - LoadFIZ_Param( xline ); - continue; - } + startBPT = false; + fizlines.emplace( "Param", inputline ); + LoadFIZ_Param( inputline ); + continue; + } - if (issection("Load:")) - { - startBPT = false; - secLoad = true; - bMaxLoad = atoi(getkeyval(2, "MaxLoad").c_str()); - bLoadQ = getkeyval(1, "LoadQ"); - bLoadAccepted = getkeyval(1, "LoadAccepted"); - bLoadSpeed = atof(getkeyval(3, "LoadSpeed").c_str()); - bUnLoadSpeed = atof(getkeyval(3, "UnLoadSpeed").c_str()); - bOverLoadFactor = atof(getkeyval(3, "OverLoadFactor").c_str()); - continue; - } + if( issection( "Load:", inputline ) ) + { + startBPT = false; + fizlines.emplace( "Load", inputline ); + LoadFIZ_Load( inputline ); + continue; + } - if( issection( "Doors:" ) ) { + if( issection( "Dimensions:", inputline ) ) + { + startBPT = false; + fizlines.emplace( "Dimensions", inputline ); + LoadFIZ_Dimensions( inputline ); + continue; + } - startBPT = false; - LoadFIZ_Doors( xline ); - continue; - } + if( issection( "Wheels:", inputline ) ) + { + startBPT = false; + fizlines.emplace( "Wheels", inputline ); + LoadFIZ_Wheels( inputline ); + continue; + } - if (issection("Dimensions:")) - { - startBPT = false; - secDimensions = true; - SetFlag(OKFlag, dimensions_ok); - cL = atof(getkeyval(3, "L").c_str()); - cH = atof(getkeyval(3, "H").c_str()); - cW = atof(getkeyval(3, "W").c_str()); - cCx = atof(getkeyval(3, "Cx").c_str()); - cFloor = atof(getkeyval(3, "Floor").c_str()); - continue; - } + if( issection( "Brake:", inputline ) ) + { + startBPT = false; + fizlines.emplace( "Brake", inputline ); + LoadFIZ_Brake( inputline ); + continue; + } - if (issection("Wheels:")) - { - startBPT = false; - secWheels = true; - dD = atof(getkeyval(3, "D").c_str()); - dDl = atof(getkeyval(3, "Dl").c_str()); - dDt = atof(getkeyval(3, "Dt").c_str()); - dAIM = atof(getkeyval(3, "AIM").c_str()); - dTw = atof(getkeyval(3, "Tw").c_str()); - dAxle = getkeyval(1, "Axle"); - dAd = atof(getkeyval(3, "Ad").c_str()); - dBd = atof(getkeyval(3, "Bd").c_str()); - dRmin = atof(getkeyval(3, "Rmin").c_str()); - dBearingType = getkeyval(1, "BearingType"); - continue; - } + if( issection( "Doors:", inputline ) ) { - if (issection("Brake:")) - { - startBPT = false; - secBrake = true; - eBrakeValve = getkeyval(1, "BrakeValve"); - eNBpA = atoi(getkeyval(2, "NBpA").c_str()); - eMBF = atof(getkeyval(3, "MBF").c_str()); - eTBF = atof(getkeyval(3, "TBF").c_str()); - eSize = atoi(getkeyval(3, "Size").c_str()); - eMaxBP = atof(getkeyval(3, "MaxBP").c_str()); - eMedMaxBP = atof(getkeyval(3, "MedMaxBP").c_str()); - eTareMaxBP = atof(getkeyval(3, "TareMaxBP").c_str()); - eMaxLBP = atof(getkeyval(3, "MaxLBP").c_str()); - eMaxASBP = atof(getkeyval(3, "MaxASBP").c_str()); - eRM = atof(getkeyval(3, "RM").c_str()); - eBCN = atoi(getkeyval(2, "BCN").c_str()); - eBCR = atof(getkeyval(3, "BCR").c_str()); - eBCD = atof(getkeyval(3, "BCD").c_str()); - eBCM = atof(getkeyval(3, "BCM").c_str()); - eBCMlo = atof(getkeyval(3, "BCMlo").c_str()); - eBCMhi = atof(getkeyval(3, "BCMhi").c_str()); - eVv = atof(getkeyval(3, "Vv").c_str()); - eMinCP = atof(getkeyval(3, "MinCP").c_str()); - eMaxCP = atof(getkeyval(3, "MaxCP").c_str()); - eBCS = atof(getkeyval(3, "BCS").c_str()); - eBSA = atof(getkeyval(3, "BSA").c_str()); - eBM = (getkeyval(1, "BM")); - eBVV = atoi(getkeyval(2, "BVV").c_str()); - eBRE = atof(getkeyval(3, "BRE").c_str()); - eHiPP = atof(getkeyval(3, "HiPP").c_str()); - eLoPP = atof(getkeyval(3, "LoPP").c_str()); - eCompressorSpeed = atof(getkeyval(3, "CompressorSpeed").c_str()); - eCompressorPower = atof(getkeyval(1, "CompressorPower").c_str()); - continue; - } + startBPT = false; + fizlines.emplace( "Doors", inputline ); + LoadFIZ_Doors( inputline ); + continue; + } - if( issection( "BuffCoupl." ) ) { + if( issection( "BuffCoupl.", inputline ) ) { - startBPT = false; - secBuffCoupl = true; - LoadFIZ_BuffCoupl( xline, 0 ); - continue; - } + startBPT = false; + fizlines.emplace( "BuffCoupl", inputline ); + LoadFIZ_BuffCoupl( inputline, 0 ); + continue; + } - else if( issection( "BuffCoupl1." ) ) { + else if( issection( "BuffCoupl1.", inputline ) ) { - startBPT = false; - secBuffCoupl = true; - LoadFIZ_BuffCoupl( xline, 1 ); - continue; - } + startBPT = false; + fizlines.emplace( "BuffCoupl1", inputline ); + LoadFIZ_BuffCoupl( inputline, 1 ); + continue; + } - else if( issection( "BuffCoupl2." ) ) { + else if( issection( "BuffCoupl2.", inputline ) ) { - startBPT = false; - secBuffCoupl = true; - LoadFIZ_BuffCoupl( xline, 2 ); - continue; - } + startBPT = false; + fizlines.emplace( "BuffCoupl2", inputline ); + LoadFIZ_BuffCoupl( inputline, 2 ); + continue; + } - if (issection("Security:")) - { - startBPT = false; - secSecurity = true; - hAwareSystem = (getkeyval(1, "AwareSystem")); - hAwareMinSpeed = atof(getkeyval(3, "AwareMinSpeed").c_str()); - hAwareDelay = atof(getkeyval(3, "AwareDelay").c_str()); - hSoundSignalDelay = atof(getkeyval(3, "SoundSignalDelay").c_str()); - hEmergencyBrakeDelay = atof(getkeyval(3, "EmergencyBrakeDelay").c_str()); - hRadioStop = (getkeyval(1, "RadioStop")); - continue; - } + if( issection( "TurboPos:", inputline ) ) { - if (issection("Light:")) - { - startBPT = false; - secLight = true; - iLight = (getkeyval(1, "Light")); - iLGeneratorEngine = (getkeyval(1, "LGeneratorEngine")); - iLMaxVoltage = atof(getkeyval(3, "LMaxVoltage").c_str()); - iLMaxCurrent = atof(getkeyval(3, "LMaxCurrent").c_str()); - continue; - } + startBPT = false; + fizlines.emplace( "TurboPos", inputline ); + LoadFIZ_TurboPos( inputline ); + continue; + } - if (issection("Power:")) - { - startBPT = false; - secPower = true; - jEnginePower = (getkeyval(1, "EnginePower")); - jSystemPower = (getkeyval(1, "SystemPower")); - jCollectorsNo = atoi(getkeyval(2, "CollectorsNo").c_str()); - jMaxVoltage = atof(getkeyval(3, "MaxVoltage").c_str()); - jMaxCurrent = atof(getkeyval(3, "MaxCurrent").c_str()); - jIntR = atof(getkeyval(3, "IntR").c_str()); - jMinH = atof(getkeyval(3, "MinH").c_str()); - jMaxH = atof(getkeyval(3, "MaxH").c_str()); - jCSW = atof(getkeyval(3, "CSW").c_str()); - jMinV = atof(getkeyval(3, "MinV").c_str()); - jMinPress = atof(getkeyval(3, "MinPress").c_str()); - jMaxPress = atof(getkeyval(3, "MaxPress").c_str()); - continue; - } + if( issection( "Cntrl.", inputline ) ) { - if (issection("Engine:")) - { - startBPT = false; - secEngine = true; - kEngineType = (getkeyval(1, "EngineType")); - kTrans = (getkeyval(1, "Trans")); - kVolt = atof(getkeyval(3, "Volt").c_str()); - kWindingRes = atof(getkeyval(3, "WindingRes").c_str()); - kNMax = atof(getkeyval(3, "nmax").c_str()); - // new (diesel) engine parameters follow - // TODO: check if the entries are correct. - // TODO, TBD: possibly read the values into module variables first, instead of injecting them directly into the engine? - getkeyval( kshuntmode, "ShuntMode", xline, "0.0" ); - int flat; - getkeyval( flat, "Flat", xline, "0" ); Flat = ( flat == 1 ); - // diesel-electric - getkeyval( Ftmax, "Ftmax", xline, "" ); - getkeyval( Vhyp, "Vhyp", xline, "" ); - getkeyval( Vadd, "Vadd", xline, "" ); - getkeyval( PowerCorRatio, "Cr", xline, "" ); - getkeyval( AutoRelayType, "RelayType", xline, "" ); - // diesel - getkeyval( dizel_nmin, "nmin", xline, "" ); - getkeyval( dizel_nmax, "nmax", xline, "" ); - getkeyval( dizel_nmax_cutoff, "nmax_cutoff", xline, "0.0" ); - getkeyval( dizel_AIM, "AIM", xline, "1.0" ); - // electric induction - getkeyval( eimc[ eimc_s_dfic ], "dfic", xline, "" ); - getkeyval( eimc[ eimc_s_dfmax ], "dfmax", xline, "" ); - getkeyval( eimc[ eimc_s_p ], "p", xline, "" ); - getkeyval( eimc[ eimc_s_cfu ], "cfu", xline, "" ); - getkeyval( eimc[ eimc_s_cim ], "cim", xline, "" ); - getkeyval( eimc[ eimc_s_icif ], "icif", xline, "" ); - getkeyval( eimc[ eimc_f_Uzmax ], "Uzmax", xline, "" ); - getkeyval( eimc[ eimc_f_Uzh ], "Uzh", xline, "" ); - getkeyval( eimc[ eimc_f_DU ], "DU", xline, "" ); - getkeyval( eimc[ eimc_f_I0 ], "I0", xline, "" ); - getkeyval( eimc[ eimc_f_cfu ], "fcfu", xline, "" ); - getkeyval( eimc[ eimc_p_F0 ], "F0", xline, "" ); - getkeyval( eimc[ eimc_p_a1 ], "a1", xline, "" ); - getkeyval( eimc[ eimc_p_Pmax ], "Pmax", xline, "" ); - getkeyval( eimc[ eimc_p_Fh ], "Fh", xline, "" ); - getkeyval( eimc[ eimc_p_Ph ], "Ph", xline, "" ); - getkeyval( eimc[ eimc_p_Vh0 ], "Vh0", xline, "" ); - getkeyval( eimc[ eimc_p_Vh1 ], "Vh1", xline, "" ); - getkeyval( eimc[ eimc_p_Imax ], "Imax", xline, "" ); - getkeyval( eimc[ eimc_p_abed ], "abed", xline, "" ); - getkeyval( eimc[ eimc_p_eped ], "edep", xline, "" ); - - continue; - } + startBPT = true; LISTLINE = 0; + fizlines.emplace( "Cntrl", inputline ); + LoadFIZ_Cntrl( inputline ); + continue; + } - if (issection("Circuit:")) - { - startBPT = false; - secCircuit = true; - lCircuitRes = atof(getkeyval(3, "CircuitRes").c_str()); - lImaxLo = atoi(getkeyval(2, "ImaxLo").c_str()); - lImaxHi = atoi(getkeyval(2, "ImaxHi").c_str()); - lIminLo = atoi(getkeyval(2, "IminLo").c_str()); - lIminHi = atoi(getkeyval(2, "IminHi").c_str()); - continue; - } + if( issection( "Light:", inputline ) ) { - if (issection("RList:")) - { - startBPT = false; - secRList = true; - mSize = atoi(getkeyval(2, "Size").c_str()); - mRVent = (getkeyval(1, "RVent")); - mRVentnmax = atof(getkeyval(3, "RVentnmax").c_str()); - mRVentCutOff = atof(getkeyval(3, "RVentCutOff").c_str()); - // don't close loop yet, init data table - } + startBPT = false; + fizlines.emplace( "Light", inputline ); + LoadFIZ_Light( inputline ); + continue; + } - if( issection( "RList:" ) || startRLIST ) { - startBPT = false; - secRList = true; - readRList( RLISTLINE, xline ); - continue; - } + if( issection( "Security:", inputline ) ) + { + startBPT = false; + fizlines.emplace( "Security", inputline ); + LoadFIZ_Security( inputline ); + continue; + } - if( issection( "DList:" ) ) - { - startBPT = false; - secDList = true; - startDLIST = true; DLISTLINE = 0; - nMmax = atof(getkeyval(3, "Mmax").c_str()); - nnMmax = atof(getkeyval(3, "nMmax").c_str()); - nMnmax = atof(getkeyval(3, "Mnmax").c_str()); - nnmax = atof(getkeyval(3, "nmax").c_str()); - nnominalfill = atof(getkeyval(3, "nominalfill").c_str()); - nMstand = atof(getkeyval(3, "Mstand").c_str()); - nSize = atoi(getkeyval(2, "Size").c_str()); + if( issection( "Clima:", inputline ) ) { - if( kEngineType == "DieselEngine" ) { - // TODO: does the diesel really need duplicate of common variables :x - // TODO, TBD: pass the values through module variables instead of injecting them directly? - getkeyval( dizel_Mmax, "Mmax", xline, "" ); - getkeyval( dizel_nMmax, "nMmax", xline, "" ); - getkeyval( dizel_Mnmax, "Mnmax", xline, "" ); - getkeyval( dizel_nmax, "nmax", xline, "" ); - getkeyval( dizel_nominalfill, "nominalfill", xline, "" ); - getkeyval( dizel_Mstand, "Mstand", xline, "" ); - } - continue; - } + startBPT = false; + fizlines.emplace( "Clima", inputline ); + LoadFIZ_Clima( inputline ); + continue; + } - if( issection( "ffList:" ) ) { - startBPT = false; - secffList = true; - startFFLIST = true; FFLISTLINE = 0; - continue; - } + if( issection( "Power:", inputline ) ) + { + startBPT = false; + fizlines.emplace( "Power", inputline ); + LoadFIZ_Power( inputline ); + continue; + } - if( issection( "WWList:" ) ) - { - startBPT = false; - secWWList = true; - startWWLIST = true; WWLISTLINE = 0; - continue; - } + if( issection( "Engine:", inputline ) ) + { + startBPT = false; + fizlines.emplace( "Engine", inputline ); + LoadFIZ_Engine( inputline ); + continue; + } - if (issection("TurboPos:")) - { - startBPT = false; - secTurboPos = true; - getkeyval( TurboTest, "TurboPos", xline, "" ); - continue; - } + if( issection( "Switches:", inputline ) ) { + startBPT = false; + fizlines.emplace( "Switches", inputline ); + LoadFIZ_Switches( inputline ); + continue; + } - if (issection("MotorParamTable0:") ) - { - startBPT = false; - startMPT0 = true; MPTLINE = 0; - secMotorParamTable = true; - continue; - } + if( issection( "MotorParamTable:", inputline ) ) { + startBPT = false; + startMPT = true; LISTLINE = 0; + fizlines.emplace( "MotorParamTable", inputline ); + LoadFIZ_MotorParamTable( inputline ); + continue; + } - if( issection( "MotorParamTable:" ) ) { - // diesel engine variant - startBPT = false; - startMPT = true; MPTLINE = 0; - secMotorParamTable = true; - // variables - if( kEngineType == "DieselEngine" ) { - getkeyval( dizel_minVelfullengage, "minVelfullengage", xline, "" ); - getkeyval( dizel_engageDia, "engageDia", xline, "" ); - getkeyval( dizel_engageMaxForce, "engageMaxForce", xline, "" ); - getkeyval( dizel_engagefriction, "engagefriction", xline, "" ); - } - continue; - } + if( issection( "MotorParamTable0:", inputline ) ) { + startBPT = false; + startMPT0 = true; LISTLINE = 0; + continue; + } - if( issection( "Cntrl." ) ) { - startBPT = true; BPTLINE = 0; - secCntrl = true; - gBrakeSystem = ( getkeyval( 1, "BrakeSystem" ) ); - gBCPN = atoi( getkeyval( 2, "BCPN" ).c_str() ); - gBDelay1 = atoi( getkeyval( 2, "BDelay1" ).c_str() ); - gBDelay2 = atoi( getkeyval( 2, "BDelay2" ).c_str() ); - gBDelay3 = atoi( getkeyval( 2, "BDelay3" ).c_str() ); - gBDelay4 = atoi( getkeyval( 2, "BDelay4" ).c_str() ); - gASB = ( getkeyval( 1, "ASB" ) ); - gLocalBrake = ( getkeyval( 1, "LocalBrake" ) ); - gDynamicBrake = ( getkeyval( 1, "DynamicBrake" ) ); - // gManualBrake = (getkeyval(1, "ManualBrake")); - gFSCircuit = ( getkeyval( 1, "FSCircuit" ).c_str() ); - gMCPN = atoi( getkeyval( 2, "MCPN" ).c_str() ); - gSCPN = atoi( getkeyval( 2, "SCPN" ).c_str() ); - gSCIM = atoi( getkeyval( 2, "SCIM" ).c_str() ); - gScndS = ( getkeyval( 1, "ScndS" ) ); - gCoupledCtrl = ( getkeyval( 1, "CoupledCtrl" ) ); - gAutoRelay = ( getkeyval( 1, "AutoRelay" ) ); - gIniCDelay = atof( getkeyval( 3, "IniCDelay" ).c_str() ); - gSCDelay = atof( getkeyval( 3, "SCDelay" ).c_str() ); - gSCDDelay = atof( getkeyval( 3, "SCDDelay" ).c_str() ); - gBrakeDelays = ( getkeyval( 1, "BrakeDelays" ) ); - gBrakeHandle = ( getkeyval( 1, "BrakeHandle" ) ); - gLocBrakeHandle = ( getkeyval( 1, "LocBrakeHandle" ) ); - gMaxBPMass = atof( getkeyval( 3, "MaxBPMass" ).c_str() ); - continue; - } - // ...and finally, table parsers. - // NOTE: once table parsing is enabled it lasts until switched off, when another section is recognized - if( true == startBPT ) { - readBPT( xline ); - continue; - } - if( true == startMPT ) { - readMPT( xline ); - continue; - } - if( true == startMPT0 ) { - readMPT0( xline ); - continue; - } - if( true == startDLIST ) { - readDList( xline ); - continue; - } - if( true == startFFLIST ) { - readFFList( xline ); - continue; - } - if( true == startWWLIST ) { - readWWList( xline ); - continue; - } - } // is hash + if( issection( "Circuit:", inputline ) ) + { + startBPT = false; + fizlines.emplace( "Circuit", inputline ); + LoadFIZ_Circuit( inputline ); + continue; + } + + if( issection( "RList:", inputline ) ) + { + startBPT = false; + fizlines.emplace( "RList", inputline ); + startRLIST = true; LISTLINE = 0; + LoadFIZ_RList( inputline ); + continue; + } + + if( issection( "DList:", inputline ) ) + { + startBPT = false; + fizlines.emplace( "DList", inputline ); + startDLIST = true; LISTLINE = 0; + LoadFIZ_DList( inputline ); + continue; + } + + if( issection( "ffList:", inputline ) ) { + startBPT = false; + startFFLIST = true; LISTLINE = 0; + continue; + } + + if( issection( "WWList:", inputline ) ) + { + startBPT = false; + startWWLIST = true; LISTLINE = 0; + continue; + } + + if( issection( "LightsList:", inputline ) ) { + startBPT = false; + fizlines.emplace( "LightsList", inputline ); + startLIGHTSLIST = true; LISTLINE = 0; + LoadFIZ_LightsList( inputline ); + continue; + } + + // ...and finally, table parsers. + // NOTE: once table parsing is enabled it lasts until switched off, when another section is recognized + if( true == startBPT ) { + readBPT( inputline ); + continue; + } + if( true == startMPT ) { + readMPT( inputline ); + continue; + } + if( true == startMPT0 ) { + readMPT0( inputline ); + continue; + } + if( true == startRLIST ) { + readRList( inputline ); + continue; + } + if( true == startDLIST ) { + readDList( inputline ); + continue; + } + if( true == startFFLIST ) { + readFFList( inputline ); + continue; + } + if( true == startWWLIST ) { + readWWList( inputline ); + continue; + } + if( true == startLIGHTSLIST ) { + readLightsList( inputline ); + continue; + } } // while line in.close(); - // Sprawdzenie poprawnosci wczytanych parametrow - // WriteLog("DATA TEST: " + aCategory + ", " + aType + ", " + bLoadQ + ", " + bLoadAccepted + ", - // " + dAxle + ", " + dBearingType + ", " + eBrakeValve + ", " + eBM + ", " + jEnginePower + ", - // " + kEngineType + ", " + mRVent ); - // WriteLog("BPT Table:"); - // string str; - // for (TBrakePressureTable::iterator it = BrakePressureTable.begin(); - // it != BrakePressureTable.end(); ++it) - // { - // str = to_string(it->first) + " " + to_string(it->second.PipePressureVal) + " " + - // to_string(it->second.BrakePressureVal) + " " + - // to_string(it->second.FlowSpeedVal); - // WriteLog(str); - // } // WriteLog(" "); // Operacje na zebranych parametrach - przypisywanie do wlasciwych zmiennych i ustawianie // zaleznosci - LoadAccepted = ToLower( bLoadAccepted ); - MaxLoad = bMaxLoad; - LoadQuantity = bLoadQ; - OverLoadFactor = bOverLoadFactor; - LoadSpeed = bLoadSpeed; - UnLoadSpeed = bUnLoadSpeed; - Dim.L = cL; - Dim.W = cW; - Dim.H = cH; - Cx = cCx; - - if (Cx == 0) - Cx = 0.3; - if (cFloor == -1) - { - if (Dim.H <= 2.0) - Floor = Dim.H; // gdyby nie było parametru, lepsze to niż zero - else - Floor = 0.0; // zgodność wsteczna - } - else - Floor = cFloor; - - // Axles - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - WheelDiameter = dD; - WheelDiameterL = dDl; - WheelDiameterT = dDt; - TrackW = dTw; - AxleInertialMoment = dAIM; - AxleArangement = dAxle; - NPoweredAxles = s2NPW(AxleArangement); - NAxles = NPoweredAxles + s2NNW(AxleArangement); - BearingType = 1; - ADist = dAd; - BDist = dBd; - - if (WheelDiameterL == 0.0) // gdyby nie było parametru... - WheelDiameterL = WheelDiameter; //... lepsze to niż zero - else - WheelDiameterL = dDl; - if (WheelDiameterT == 0.0) // gdyby nie było parametru... - WheelDiameterT = WheelDiameter; //... lepsze to niż zero - else - WheelDiameterT = dDt; - - if (AxleInertialMoment <= 0) - AxleInertialMoment = 1; - - if (NAxles == 0) - ConversionError = MARKERROR(-1, "1", "0 axles, hover cat?"); - - if (dBearingType == "Roll") - BearingType = 1; - else - BearingType = 0; - /* - WriteLog("CompressorPower " + eCompressorPower); - WriteLog("NAxles " + IntToStr(NAxles)); - WriteLog("BearingType " + dBearingType); - WriteLog("params " + BrakeValveParams); - WriteLog("NBpA " + IntToStr(NBpA)); - WriteLog("MaxBrakeForce " + FloatToStr(MaxBrakeForce)); - WriteLog("TrackBrakeForce " + FloatToStr(TrackBrakeForce)); - WriteLog("MaxBrakePress[3] " + to_string(MaxBrakePress[3])); - /*WriteLog("BrakeCylNo " + IntToStr(BrakeCylNo)); - WriteLog("BCD " + FloatToStr(eBCD)); - WriteLog("BCR " + FloatToStr(eBCR)); - WriteLog("BCS " + FloatToStr(eBCS)); - WriteLog("BrakeHandle " + gBrakeHandle); - WriteLog("BrakeLocHandle " + gLocBrakeHandle); - */ - - // Brakes - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - if (secBrake) - { - BrakeValveParams = eBrakeValve; - BrakeValveDecode(BrakeValveParams); - BrakeSubsystemDecode(); - NBpA = eNBpA; - MaxBrakeForce = eMBF; - BrakeValveSize = eSize; - TrackBrakeForce = eTBF * 1000; - MaxBrakePress[3] = eMaxBP; - if (MaxBrakePress[3] > 0) - { - BrakeCylNo = eBCN; - if (BrakeCylNo > 0) - { - MaxBrakePress[0] = eMaxLBP; - if (MaxBrakePress[0] < 0.01) - MaxBrakePress[0] = MaxBrakePress[3]; - MaxBrakePress[1] = eTareMaxBP; - MaxBrakePress[2] = eMedMaxBP; - MaxBrakePress[4] = eMaxASBP; - if (MaxBrakePress[4] < 0.01) - MaxBrakePress[4] = 0; - BrakeCylRadius = eBCR; - BrakeCylDist = eBCD; - BrakeCylSpring = eBCS; - BrakeSlckAdj = eBSA; - if (eBRE != 0) - BrakeRigEff = eBRE; - else - BrakeRigEff = 1; - BrakeCylMult[0] = eBCM; - BrakeCylMult[1] = eBCMlo; - BrakeCylMult[2] = eBCMhi; - P2FTrans = 100.0 * PI * sqr(BrakeCylRadius); // w kN/bar Q: zamieniam SQR() na - // sqr() - if ((BrakeCylMult[1] > 0) || (MaxBrakePress[1] > 0)) - LoadFlag = 1; - else - LoadFlag = 0; // Q: zamieniam SQR() na sqr() - BrakeVolume = PI * sqr(BrakeCylRadius) * BrakeCylDist * BrakeCylNo; - BrakeVVolume = eBVV; - if (eBM == "P10-Bg") - BrakeMethod = bp_P10Bg; - else if (eBM == "P10-Bgu") - BrakeMethod = bp_P10Bgu; - else if (eBM == "FR513") - BrakeMethod = bp_FR513; - else if (eBM == "Cosid") - BrakeMethod = bp_Cosid; - else if (eBM == "P10yBg") - BrakeMethod = bp_P10yBg; - else if (eBM == "P10yBgu") - BrakeMethod = bp_P10yBgu; - else if (eBM == "Disk1") - BrakeMethod = bp_D1; - else if (eBM == "Disk1+Mg") - BrakeMethod = bp_D1 + bp_MHS; - else if (eBM == "Disk2") - BrakeMethod = bp_D2; - else - BrakeMethod = 0; - if (eRM != 0) - RapidMult = eRM; - else - RapidMult = 1; - } - else - ConversionError = MARKERROR(-5, "1", "0 brake cylinder units"); - } - else - P2FTrans = 0; - - // WriteLog("eBM=" + eBM + ", " + IntToStr(0)); - - if (eHiPP != 0) - CntrlPipePress = eHiPP; - else - CntrlPipePress = - 5.0 + 0.001 * (Random(10) - Random(10)); // Ra 2014-07: trochę niedokładności - HighPipePress = CntrlPipePress; - - if (eHiPP != 0) - LowPipePress = eLoPP; - else - LowPipePress = Min0R(HighPipePress, 3.5); - - DeltaPipePress = HighPipePress - LowPipePress; - - VeselVolume = eVv; - if (VeselVolume == 0) - VeselVolume = 0.01; - - MinCompressor = eMinCP; - MaxCompressor = eMaxCP; - CompressorSpeed = eCompressorSpeed; - - if (eCompressorPower == "Converter") - CompressorPower = 2; - else if (eCompressorPower == "Engine") - CompressorPower = 3; - else if (eCompressorPower == "Coupler1") - CompressorPower = 4; - else // włączana w silnikowym EZT z przodu - if (eCompressorPower == "Coupler2") - CompressorPower = 5; - else // włączana w silnikowym EZT z tyłu - if (eCompressorPower == "Main") - CompressorPower = 0; - - // WriteLog("params " + BrakeValveParams); - // WriteLog("NBpA " + IntToStr(NBpA)); - // WriteLog("MaxBrakeForce " + FloatToStr(MaxBrakeForce)); - // WriteLog("TrackBrakeForce " + FloatToStr(TrackBrakeForce)); - // WriteLog("MaxBrakePress[3] " + FloatToStr(MaxBrakePress[3])); - // WriteLog("BrakeCylNo " + IntToStr(BrakeCylNo)); - } - - // Controllers - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - if (secCntrl) - { - if (gBrakeSystem == "Pneumatic") - BrakeSystem = Pneumatic; - else if (gBrakeSystem == "ElectroPneumatic") - BrakeSystem = ElectroPneumatic; - else - BrakeSystem = Individual; - - if (BrakeSystem != Individual) - { - - BrakeCtrlPosNo = gBCPN; - BrakeDelay[1] = gBDelay1; - // BrakeDelay[2] = gBDelay2; - // BrakeDelay[3] = gBDelay3; - // BrakeDelay[4] = gBDelay4; - - if (gBrakeDelays == "GPR") - BrakeDelays = bdelay_G | bdelay_P | bdelay_R; - else if (gBrakeDelays == "PR") - BrakeDelays = bdelay_P | bdelay_R; - else if (gBrakeDelays == "GP") - BrakeDelays = bdelay_G | bdelay_P; - else if (gBrakeDelays == "R") - { - BrakeDelays = bdelay_R; - BrakeDelayFlag = bdelay_R; - } - else if (gBrakeDelays == "P") - { - BrakeDelays = bdelay_P; - BrakeDelayFlag = bdelay_P; - } - else if (gBrakeDelays == "G") - { - BrakeDelays = bdelay_G; - BrakeDelayFlag = bdelay_G; - } - else if (gBrakeDelays == "GPR+Mg") - BrakeDelays = bdelay_G | bdelay_P | bdelay_R | bdelay_M; - else if (gBrakeDelays == "PR+Mg") - BrakeDelays = bdelay_P | bdelay_R | bdelay_M; - - if (gBrakeHandle == "FV4a") - BrakeHandle = FV4a; - else if (gBrakeHandle == "test") - BrakeHandle = testH; - else if (gBrakeHandle == "D2") - BrakeHandle = D2; - else if (gBrakeHandle == "M394") - BrakeHandle = M394; - else if (gBrakeHandle == "Knorr") - BrakeHandle = Knorr; - else if (gBrakeHandle == "Westinghouse") - BrakeHandle = West; - else if (gBrakeHandle == "FVel6") - BrakeHandle = FVel6; - else if (gBrakeHandle == "St113") - BrakeHandle = St113; - - if (gLocBrakeHandle == "FD1") - BrakeLocHandle = FD1; - else if (gLocBrakeHandle == "Knorr") - BrakeLocHandle = Knorr; - else if (gLocBrakeHandle == "Westinghouse") - BrakeLocHandle = West; - - if (gMaxBPMass != 0) - MBPM = gMaxBPMass * 1000; - - if (BrakeCtrlPosNo > 0) - { - if (gASB == "Manual") - ASBType = 1; - else if (gASB == "Automatic") - ASBType = 2; - } - else - { - if (gASB == "Yes") - ASBType = 128; - } - } // BrakeSystem != individual - - // WriteLog("gLocalBrake " + gLocalBrake); - // WriteLog("gManualBrake " + gManualBrake); - // WriteLog("gManualBrake " + gManualBrake); - - if (gLocalBrake == "ManualBrake") - LocalBrake = ManualBrake; - else if (gLocalBrake == "PneumaticBrake") - LocalBrake = PneumaticBrake; - else if (gLocalBrake == "HydraulicBrake") - LocalBrake = HydraulicBrake; - else - LocalBrake = NoBrake; - - if (gManualBrake == "Yes") - MBrake = true; - else - MBrake = false; - - if (gDynamicBrake == "Passive") - DynamicBrakeType = dbrake_passive; - else if (gDynamicBrake == "Switch") - DynamicBrakeType = dbrake_switch; - else if (gDynamicBrake == "Reversal") - DynamicBrakeType = dbrake_reversal; - else if (gDynamicBrake == "Automatic") - DynamicBrakeType = dbrake_automatic; - else - DynamicBrakeType = dbrake_none; - - MainCtrlPosNo = gMCPN; - - ScndCtrlPosNo = gSCPN; - - ScndInMain = bool(gSCIM); - - if (gAutoRelay == "Optional") - AutoRelayType = 2; - else if (gAutoRelay == "Yes") - AutoRelayType = 1; - else - AutoRelayType = 0; - - if (gCoupledCtrl == "Yes") - CoupledCtrl = true; - else // wspolny wal - CoupledCtrl = false; - - if (gScndS == "Yes") - ScndS = true; // brak pozycji rownoleglej przy niskiej nastawie PSR} - else - ScndS = false; - - InitialCtrlDelay = gIniCDelay; - CtrlDelay = gSCDelay; - - if (gSCDDelay > 0) - CtrlDownDelay = gSCDDelay; - else - CtrlDownDelay = CtrlDelay; // hunter-101012: jesli nie ma SCDDelay; - - if (gFSCircuit == "Yes") - FastSerialCircuit = 1; - else - FastSerialCircuit = 0; - } - - // Security System - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - if (secSecurity) - { - if (Pos("Active", hAwareSystem) > 0) - SetFlag(SecuritySystem.SystemType, 1); - if (Pos("CabSignal", hAwareSystem) > 0) - SetFlag(SecuritySystem.SystemType, 2); - if (hAwareDelay > 0) - SecuritySystem.AwareDelay = hAwareDelay; - if (hAwareMinSpeed > 0) - SecuritySystem.AwareMinSpeed = hAwareMinSpeed; - else - SecuritySystem.AwareMinSpeed = 0.1 * Vmax; // domyślnie 10% Vmax - if (hSoundSignalDelay > 0) - SecuritySystem.SoundSignalDelay = hSoundSignalDelay; - if (hEmergencyBrakeDelay > 0) - SecuritySystem.EmergencyBrakeDelay = hEmergencyBrakeDelay; - if (Pos("Yes", hRadioStop) > 0) - SecuritySystem.RadioStop = true; - } - - // Power - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - if (secPower) - { - // WriteLog("EnginePower " + jEnginePower); - - if (jEnginePower != "") - { - // s:=DUE(ExtractKeyWord(lines,'EnginePower=')); - if (jEnginePower != "") - { - EnginePowerSource.SourceType = PowerSourceDecode(jEnginePower); - PowerParamDecode(xline, "", EnginePowerSource); - - if ((EnginePowerSource.SourceType == Generator) && - (EnginePowerSource.GeneratorEngine == WheelsDriven)) - ConversionError = -666; // perpetuum mobile?} - if (Power == 0) // jeśli nie ma mocy, np. rozrządcze EZT - EnginePowerSource.SourceType = NotDefined; // to silnik nie ma zasilania - } - else - EnginePowerSource.SourceType = NotDefined; - - if (jSystemPower != "") - { - SystemPowerSource.SourceType = PowerSourceDecode(jSystemPower); - PowerParamDecode(xline, "", SystemPowerSource); - } - else - SystemPowerSource.SourceType = NotDefined; - } - jEnginePower = ""; // zeby nastepny pojad mial zresetowane na poczatku wczytywania - } - - // Engine - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - if (secEngine) - { - if (kEngineType != "") - { - EngineType = EngineDecode(kEngineType); - - if( false == kTrans.empty() ) { - // transmission type. moved here because more than one engine type has this entry - x = Split( kTrans, ':' ); // 18:79 - - if( x.size() != 2 ) { - ErrorLog( "Wrong transmition definition: " + kTrans ); - } - - p0 = TrimSpace( x[ 0 ] ); - p1 = TrimSpace( x[ 1 ] ); - - Transmision.NToothW = atoi( p1.c_str() ); - Transmision.NToothM = atoi( p0.c_str() ); - - // ToothW to drugi parametr czyli 79 - // ToothM to pierwszy czyli 18 - - // WriteLog("trans " + IntToStr(Transmision.NToothW ) + "/" + - // IntToStr(Transmision.NToothM )); - // if (kTrans != "") - if( Transmision.NToothM > 0 ) - Transmision.Ratio = double( Transmision.NToothW ) / Transmision.NToothM; - else - Transmision.Ratio = 1; - } - - // engine type specific parameters - switch (EngineType) - { - - case ElectricSeriesMotor: - { - NominalVoltage = kVolt; - - if( kWindingRes != 0.0 ) { WindingRes = kWindingRes; } - else { WindingRes = 0.01; } - // WriteLog("WindingRes " + FloatToStr(WindingRes)); - - nmax = kNMax / 60.0; - // WriteLog("nmax " + FloatToStr(nmax )); - - if( kshuntmode == 1.0 ) { - // shuntmode - ShuntModeAllow = true; - ShuntMode = false; - AnPos = 0.0; - ImaxHi = 2; - ImaxLo = 1; - } - break; - } - - case DieselEngine: { - - dizel_nmin /= 60.0; - dizel_nmax /= 60.0; - dizel_nmax_cutoff /= 60; - // NOTE: dizel_nmax seems to be duplicate of nmax. - // keep an eye on nmax being used in equations associated with DieselEngine - // as temporary work-around for potential errors the 'regular' nmax is also given the matching value here - nmax = dizel_nmax; - - if( kshuntmode > 0.0 ) { - // shuntmode - ShuntModeAllow = true; - ShuntMode = false; - AnPos = kshuntmode; //dodatkowe przełożenie - if( AnPos < 1.0 ) { - //"rozruch wysoki" ma dawać większą siłę; im większa liczba, tym wolniej jedzie - AnPos = 1.0 / AnPos; - } - } - - break; - } - - } // switch - } - } - - // Circuit - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - if (secCircuit) - { - // s := DUE(ExtractKeyWord(lines, 'CircuitRes=')); writepaslog('CircuitRes', s); - CircuitRes = (lCircuitRes); - - // s := DUE(ExtractKeyWord(lines, 'IminLo=')); writepaslog('IminLo', s); - IminLo = (lIminLo); - - // s := DUE(ExtractKeyWord(lines, 'IminHi=')); writepaslog('IminHi', s); - IminHi = (lIminHi); - - // s := DUE(ExtractKeyWord(lines, 'ImaxLo=')); writepaslog('ImaxLo', s); - ImaxLo = (lImaxLo); - - // s := DUE(ExtractKeyWord(lines, 'ImaxHi=')); writepaslog('ImaxHi', s); - ImaxHi = (lImaxHi); - Imin = IminLo; - Imax = ImaxLo; - } - - // RList - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - if (secRList) - { - RlistSize = (mSize); - - if (mRVent == "Automatic") - RVentType = 2; - else if (mRVent == "Yes") - RVentType = 1; - else - RVentType = 0; - - if (RVentType > 0) - { - RVentnmax = (mRVentnmax) / 60.0; - - RVentCutOff = (mRVentCutOff); - } - } - + bool result; if (ConversionError == 0) - OK = true; + result = true; else - OK = false; + result = false; - // WriteLog(""); - // WriteLog("----------------------------------------------------------------------------------------"); - WriteLog("CERROR: " + to_string(ConversionError) + ", SUCCES: " + to_string(OK)); - // WriteLogSS(); - //WriteLog(""); - return OK; -} // LoadFIZ() - -bool TMoverParameters::LoadFIZ_Doors( std::string const &line ) { - - DoorOpenCtrl = 0; - std::string openctrl; getkeyval( openctrl, "OpenCtrl", line, "" ); - if( openctrl == "DriverCtrl" ) { DoorOpenCtrl = 1; } - - DoorCloseCtrl = 0; - std::string closectrl; getkeyval( closectrl, "CloseCtrl", line, "" ); - if( closectrl == "DriverCtrl" ) { DoorCloseCtrl = 1; } - else if( closectrl == "AutomaticCtrl" ) { DoorCloseCtrl = 2; } - - if( DoorCloseCtrl == 2 ) { getkeyval( DoorStayOpen, "DoorStayOpen", line, "" ); } - - getkeyval( DoorOpenSpeed, "OpenSpeed", line, "" ); - getkeyval( DoorCloseSpeed, "CloseSpeed", line, "" ); - getkeyval( DoorMaxShiftL, "DoorMaxShiftL", line, "" ); - getkeyval( DoorMaxShiftR, "DoorMaxShiftR", line, "" ); - - DoorOpenMethod = 2; //obrót, default - std::string openmethod; getkeyval( openmethod, "DoorOpenMethod", line, "" ); - if( openmethod == "Shift" ) { DoorOpenMethod = 1; } //przesuw - else if( openmethod == "Fold" ) { DoorOpenMethod = 3; } //3 submodele się obracają - else if( openmethod == "Plug" ) { DoorOpenMethod = 4; } //odskokowo-przesuwne - - std::string closurewarning; getkeyval( closurewarning, "DoorClosureWarning", line, "" ); - DoorClosureWarning = ( closurewarning == "Yes" ); - - std::string doorblocked; getkeyval( doorblocked, "DoorBlocked", line, "" ); - DoorBlocked = ( doorblocked == "Yes" ); - - getkeyval( DoorMaxPlugShift, "DoorMaxShiftPlug", line, "" ); - getkeyval( PlatformSpeed, "PlatformSpeed", line, "" ); - getkeyval( PlatformMaxShift, "PlatformMaxSpeed", line, "" ); - - PlatformOpenMethod = 2; // obrót, default - std::string platformopenmethod; getkeyval( platformopenmethod, "PlatformOpenMethod", line, "" ); - if( platformopenmethod == "Shift" ) { PlatformOpenMethod = 1; } // przesuw - - return true; + WriteLog("CERROR: " + to_string(ConversionError) + ", SUCCES: " + to_string(result)); + return result; } void TMoverParameters::LoadFIZ_Param( std::string const &line ) { - getkeyval( Mass, "M", xline, "0" ); - getkeyval( Mred, "Mred", xline, "0" ); - getkeyval( Vmax, "Vmax", xline, "0" ); - getkeyval( Power, "PWR", xline, "0" ); - getkeyval( SandCapacity, "SandCap", xline, "0" ); - getkeyval( HeatingPower, "HeatingP", xline, "0" ); - getkeyval( LightPower, "LightP", xline, "0" ); + getkeyval( Mass, "M", line, "0" ); + getkeyval( Mred, "Mred", line, "0" ); + getkeyval( Vmax, "Vmax", line, "0" ); + getkeyval( Power, "PWR", line, "0" ); + getkeyval( SandCapacity, "SandCap", line, "0" ); + getkeyval( HeatingPower, "HeatingP", line, "0" ); + getkeyval( LightPower, "LightP", line, "0" ); { std::map categories{ @@ -7235,7 +6213,7 @@ void TMoverParameters::LoadFIZ_Param( std::string const &line ) { { "ship", 4 }, { "airplane,", 8 } }; - std::string category; getkeyval( category, "Category", xline, "none" ); + std::string category; getkeyval( category, "Category", line, "none" ); auto lookup = categories.find( category ); CategoryFlag = ( lookup != categories.end() ? @@ -7259,15 +6237,15 @@ void TMoverParameters::LoadFIZ_Param( std::string const &line ) { { "181", dt_181 }, { "182", dt_181 } // na razie tak }; - std::string type; getkeyval( type, "Type", xline, "none" ); - auto lookup = types.find( ToLower(type) ); + std::string type; getkeyval( type, "Type", line, "none" ); + auto lookup = types.find( ToLower( type ) ); TrainType = ( lookup != types.end() ? lookup->second : - dt_Default ); + dt_Default ); } - if( TrainType == dt_EZT ) { + if( TrainType == dt_EZT ) { IminLo = 1; IminHi = 2; @@ -7275,6 +6253,199 @@ void TMoverParameters::LoadFIZ_Param( std::string const &line ) { } } +void TMoverParameters::LoadFIZ_Load( std::string const &line ) { + + getkeyval( LoadAccepted, "LoadAccepted", line, "" ); + if( true == LoadAccepted.empty() ) { + return; + } + + getkeyval( MaxLoad, "MaxLoad", line, "" ); + getkeyval( LoadQuantity, "LoadQ", line, "" ); + getkeyval( OverLoadFactor, "OverLoadFactor", line, "" ); + getkeyval( LoadSpeed, "LoadSpeed", line, "" ); + getkeyval( UnLoadSpeed, "UnLoadSpeed", line, "" ); +} + +void TMoverParameters::LoadFIZ_Dimensions( std::string const &line ) { + + getkeyval( Dim.L, "L", line, "" ); + getkeyval( Dim.H, "H", line, "" ); + getkeyval( Dim.W, "W", line, "" ); + getkeyval( Cx, "Cx", line, "0.3" ); + if( Dim.H <= 2.0 ) { + //gdyby nie było parametru, lepsze to niż zero + Floor = Dim.H; + } + else { + //zgodność wsteczna + Floor = 0.0; + } + getkeyval( Floor, "Floor", line, "" ); +} + +void TMoverParameters::LoadFIZ_Wheels( std::string const &line ) { + + getkeyval( WheelDiameter, "D", line, "" ); + WheelDiameterL = WheelDiameter; //gdyby nie było parametru, lepsze to niż zero + getkeyval( WheelDiameterL, "Dl", line, "" ); + WheelDiameterT = WheelDiameter; //gdyby nie było parametru, lepsze to niż zero + getkeyval( WheelDiameterT, "Dt", line, "" ); + + getkeyval( TrackW, "Tw", line, "" ); + getkeyval( AxleInertialMoment, "AIM", line, "" ); + if( AxleInertialMoment <= 0.0 ) { AxleInertialMoment = 1.0; } + + getkeyval( AxleArangement, "Axle", line, "" ); + NPoweredAxles = s2NPW( AxleArangement ); + NAxles = NPoweredAxles + s2NNW( AxleArangement ); + + BearingType = + ( extract_value( "BearingType", line ) == "Roll" ) ? + 1 : + 0; + + getkeyval( ADist, "Ad", line, "" ); + getkeyval( BDist, "Bd", line, "" ); +} + +void TMoverParameters::LoadFIZ_Brake( std::string const &line ) { + + BrakeValveDecode( extract_value( "BrakeValve", line ) ); + BrakeSubsystemDecode(); + + getkeyval( NBpA, "NBpA", line, "" ); + getkeyval( MaxBrakeForce, "MBF", line, "" ); + getkeyval( BrakeValveSize, "Size", line, "" ); + getkeyval( TrackBrakeForce, "TBF", line, "" ); TrackBrakeForce *= 1000.0; + + getkeyval( MaxBrakePress[ 3 ], "MaxBP", line, "" ); + if( MaxBrakePress[ 3 ] > 0.0 ) { + + getkeyval( BrakeCylNo, "BCN", line, "" ); + if( BrakeCylNo > 0 ) { + + getkeyval( MaxBrakePress[ 0 ], "MaxLBP", line, "" ); + if( MaxBrakePress[ 0 ] < 0.01 ) { MaxBrakePress[ 0 ] = MaxBrakePress[ 3 ]; } + getkeyval( MaxBrakePress[ 1 ], "TareMaxBP", line, "" ); + getkeyval( MaxBrakePress[ 2 ], "MedMaxBP", line, "" ); + getkeyval( MaxBrakePress[ 4 ], "MaxASBP", line, "" ); + if( MaxBrakePress[ 4 ] < 0.01 ) { MaxBrakePress[ 4 ] = 0.0; } + + getkeyval( BrakeCylRadius, "BCR", line, "" ); + getkeyval( BrakeCylDist, "BCD", line, "" ); + getkeyval( BrakeCylSpring, "BCS", line, "" ); + getkeyval( BrakeSlckAdj, "BSA", line, "" ); + getkeyval( BrakeRigEff, "BRE", line, "1" ); + + getkeyval( BrakeCylMult[ 0 ], "BCM", line, "" ); + getkeyval( BrakeCylMult[ 1 ], "BCMlo", line, "" ); + getkeyval( BrakeCylMult[ 2 ], "BCMHi", line, "" ); + + P2FTrans = 100 * M_PI * std::pow( BrakeCylRadius, 2 ); // w kN/bar + + if( ( BrakeCylMult[ 1 ] > 0.0 ) || ( MaxBrakePress[ 1 ] > 0.0 ) ) { LoadFlag = 1; } + else { LoadFlag = 0; } + + BrakeVolume = M_PI * std::pow( BrakeCylRadius, 2 ) * BrakeCylDist * BrakeCylNo; + getkeyval( BrakeVVolume, "BVV", line, "" ); + + { + std::map brakemethods{ + { "P10-Bg", bp_P10Bg }, + { "P10-Bgu", bp_P10Bgu }, + { "FR513", bp_FR513 }, + { "FR510", bp_FR510 }, + { "Cosid", bp_Cosid }, + { "P10yBg", bp_P10yBg }, + { "P10yBgu", bp_P10yBgu }, + { "Disk1", bp_D1 }, + { "Disk1+Mg", bp_D1 + bp_MHS }, + { "Disk2", bp_D2 } + }; + auto lookup = brakemethods.find( extract_value( "BM", line ) ); + BrakeMethod = + lookup != brakemethods.end() ? + lookup->second : + 0; + } + + getkeyval( RapidMult, "RM", line, "1" ); + } + } + else { + // maxbrakepress[3] == 0 or less + P2FTrans = 0; + } + + CntrlPipePress = 5 + 0.001 * ( Random( 10 ) - Random( 10 ) ); //Ra 2014-07: trochę niedokładności + getkeyval( CntrlPipePress, "HiPP", line, "" ); + HighPipePress = CntrlPipePress; + LowPipePress = std::min( HighPipePress, 3.5 ); + getkeyval( LowPipePress, "LoPP", line, "" ); + DeltaPipePress = HighPipePress - LowPipePress; + + getkeyval( VeselVolume, "Vv", line, "" ); + if( VeselVolume == 0.0 ) { VeselVolume = 0.01; } + + getkeyval( MinCompressor, "MinCP", line, "" ); + getkeyval( MaxCompressor, "MaxCP", line, "" ); + getkeyval( CompressorSpeed, "CompressorSpeed", line, "" ); + { + std::map compressorpowers{ + { "Converter", 2 }, + { "Engine", 3 }, + { "Coupler1", 4 },//włączana w silnikowym EZT z przodu + { "Coupler2", 5 },//włączana w silnikowym EZT z tyłu + { "Main", 0 } + }; + auto lookup = compressorpowers.find( extract_value( "CompressorPower", line ) ); + CompressorPower = + lookup != compressorpowers.end() ? + lookup->second : + 0; + } +} + +void TMoverParameters::LoadFIZ_Doors( std::string const &line ) { + + DoorOpenCtrl = 0; + std::string openctrl; getkeyval( openctrl, "OpenCtrl", line, "" ); + if( openctrl == "DriverCtrl" ) { DoorOpenCtrl = 1; } + + DoorCloseCtrl = 0; + std::string closectrl; getkeyval( closectrl, "CloseCtrl", line, "" ); + if( closectrl == "DriverCtrl" ) { DoorCloseCtrl = 1; } + else if( closectrl == "AutomaticCtrl" ) { DoorCloseCtrl = 2; } + + if( DoorCloseCtrl == 2 ) { getkeyval( DoorStayOpen, "DoorStayOpen", line, "" ); } + + getkeyval( DoorOpenSpeed, "OpenSpeed", line, "" ); + getkeyval( DoorCloseSpeed, "CloseSpeed", line, "" ); + getkeyval( DoorMaxShiftL, "DoorMaxShiftL", line, "" ); + getkeyval( DoorMaxShiftR, "DoorMaxShiftR", line, "" ); + + DoorOpenMethod = 2; //obrót, default + std::string openmethod; getkeyval( openmethod, "DoorOpenMethod", line, "" ); + if( openmethod == "Shift" ) { DoorOpenMethod = 1; } //przesuw + else if( openmethod == "Fold" ) { DoorOpenMethod = 3; } //3 submodele się obracają + else if( openmethod == "Plug" ) { DoorOpenMethod = 4; } //odskokowo-przesuwne + + std::string closurewarning; getkeyval( closurewarning, "DoorClosureWarning", line, "" ); + DoorClosureWarning = ( closurewarning == "Yes" ); + + std::string doorblocked; getkeyval( doorblocked, "DoorBlocked", line, "" ); + DoorBlocked = ( doorblocked == "Yes" ); + + getkeyval( DoorMaxPlugShift, "DoorMaxShiftPlug", line, "" ); + getkeyval( PlatformSpeed, "PlatformSpeed", line, "" ); + getkeyval( PlatformMaxShift, "PlatformMaxSpeed", line, "" ); + + PlatformOpenMethod = 2; // obrót, default + std::string platformopenmethod; getkeyval( platformopenmethod, "PlatformOpenMethod", line, "" ); + if( platformopenmethod == "Shift" ) { PlatformOpenMethod = 1; } // przesuw +} + void TMoverParameters::LoadFIZ_BuffCoupl( std::string const &line, int const Index ) { TCoupling *coupler; @@ -7288,8 +6459,7 @@ void TMoverParameters::LoadFIZ_BuffCoupl( std::string const &line, int const Ind { "Bare", Bare }, { "Articulated", Articulated }, }; - std::string type; getkeyval( type, "CType", line, "" ); - auto lookup = couplertypes.find( type ); + auto lookup = couplertypes.find( extract_value( "CType", line ) ); coupler->CouplerType = ( lookup != couplertypes.end() ? lookup->second : @@ -7342,20 +6512,570 @@ void TMoverParameters::LoadFIZ_BuffCoupl( std::string const &line, int const Ind if( Index == 0 ) { // 0 indicates single entry for both couplers Couplers[ 1 ] = Couplers[ 0 ]; -/* - Couplers[ 1 ].SpringKC = coupler->SpringKC; - Couplers[ 1 ].DmaxC = coupler->DmaxC; - Couplers[ 1 ].FmaxC = coupler->FmaxC; - Couplers[ 1 ].SpringKB = coupler->SpringKB; - Couplers[ 1 ].DmaxB = coupler->DmaxB; - Couplers[ 1 ].FmaxB = coupler->FmaxB; - Couplers[ 1 ].beta = coupler->beta; - Couplers[ 1 ].CouplerType = coupler->CouplerType; - Couplers[ 1 ].AllowedFlag = coupler->AllowedFlag; -*/ } } +void TMoverParameters::LoadFIZ_TurboPos( std::string const &Input ) { + + getkeyval( TurboTest, "TurboPos", Input, "" ); +} + +void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) { + + { + std::map brakesystems{ + { "Pneumatic", Pneumatic }, + { "ElectroPneumatic", ElectroPneumatic } + }; + auto lookup = brakesystems.find( extract_value( "BrakeSystem", line ) ); + BrakeSystem = + lookup != brakesystems.end() ? + lookup->second : + Individual; + } + if( BrakeSystem != Individual ) { + + getkeyval( BrakeCtrlPosNo, "BCPN", line, "" ); + for( int idx = 0; idx < 4; ++idx ) { + + getkeyval( BrakeDelay[ idx ], "BDelay" + std::to_string( idx + 1 ), line, "" ); + } + // brakedelays, brakedelayflag + { + std::map brakedelays{ + { "GPR", bdelay_G + bdelay_P + bdelay_R }, + { "PR", bdelay_P + bdelay_R }, + { "GP", bdelay_G + bdelay_P }, + { "R", bdelay_R }, + { "P", bdelay_P }, + { "G", bdelay_G }, + { "GPR+Mg", bdelay_G + bdelay_P + bdelay_R + bdelay_M }, + { "PR+Mg", bdelay_P + bdelay_R + bdelay_M } + }; + std::map brakedelayflags{ + { "R", bdelay_R }, + { "P", bdelay_P }, + { "G", bdelay_G } + }; + std::string brakedelay; + getkeyval( brakedelay, "BrakeDelays", line, "" ); + auto lookup = brakedelays.find( brakedelay ); + BrakeDelays = + lookup != brakedelays.end() ? + lookup->second : + Individual; + lookup = brakedelayflags.find( brakedelay ); + BrakeDelayFlag = + lookup != brakedelayflags.end() ? + lookup->second : + 0; + } + // brakeopmode + { + std::map brakeopmodes{ + { "PM", bom_PS + bom_PN }, + { "PNEPMED", bom_PS + bom_PN + bom_EP + bom_MED } + }; + auto lookup = brakeopmodes.find( extract_value( "BrakeOpModes", line ) ); + BrakeOpModes = + lookup != brakeopmodes.end() ? + lookup->second : + 0; + } + // brakehandle + { + std::map brakehandles{ + { "FV4a", FV4a }, + { "test", testH }, + { "D2", D2 }, + { "MHZ_EN57", MHZ_EN57 }, + { "M394", M394 }, + { "Knorr", Knorr }, + { "Westinghouse", West }, + { "FVel6", FVel6 }, + { "St113", St113 } + }; + auto lookup = brakehandles.find( extract_value( "BrakeHandle", line ) ); + BrakeHandle = + lookup != brakehandles.end() ? + lookup->second : + NoHandle; + } + // brakelochandle + { + std::map locbrakehandles{ + { "FD1", FD1 }, + { "Knorr", Knorr }, + { "Westinghouse", West } + }; + auto lookup = locbrakehandles.find( extract_value( "LocBrakeHandle", line ) ); + BrakeLocHandle = + lookup != locbrakehandles.end() ? + lookup->second : + NoHandle; + } + + // mbpm + getkeyval( MBPM, "MaxBPMass", line, "" ); + MBPM *= 1000; + + // asbtype + std::string asb; + getkeyval( asb, "ASB", line, "" ); + if( BrakeCtrlPosNo > 0 ) { + + if( asb == "Manual" ) { ASBType = 1; } + else if( asb == "Automatic" ) { ASBType = 2; } + } + else { + + if( asb == "Yes" ) { ASBType = 128; } + } + } // brakesystem != individual + + // localbrake + { + std::map localbrakes{ + { "ManualBrake", ManualBrake }, + { "PneumaticBrake", PneumaticBrake }, + { "HydraulicBrake", HydraulicBrake } + }; + auto lookup = localbrakes.find( extract_value( "LocalBrake", line ) ); + LocalBrake = + lookup != localbrakes.end() ? + lookup->second : + NoBrake; + } + // mbrake + MBrake = ( extract_value( "ManualBrake", line ) == "Yes" ); + // dynamicbrake + { + std::map dynamicbrakes{ + { "Passive", dbrake_passive }, + { "Switch", dbrake_switch }, + { "Reversal", dbrake_reversal }, + { "Automatic", dbrake_automatic } + }; + auto lookup = dynamicbrakes.find( extract_value( "DynamicBrake", line ) ); + DynamicBrakeType = + lookup != dynamicbrakes.end() ? + lookup->second : + dbrake_none; + } + + getkeyval( MainCtrlPosNo, "MCPN", line, "" ); + getkeyval( ScndCtrlPosNo, "SCPN", line, "" ); + getkeyval( ScndInMain, "SCIM", line, "" ); + + std::string autorelay; + getkeyval( autorelay, "AutoRelay", line, "" ); + if( autorelay == "Optional" ) { AutoRelayType = 2; } + else if( autorelay == "Yes" ) { AutoRelayType = 1; } + else { AutoRelayType = 0; } + + CoupledCtrl = ( extract_value( "CoupledCtrl", line ) == "Yes" ); + + ScndS = ( extract_value( "ScndS", line ) == "Yes" ); // brak pozycji rownoleglej przy niskiej nastawie PSR + + getkeyval( InitialCtrlDelay, "IniCDelay", line, "" ); + getkeyval( CtrlDelay, "SCDelay", line, "" ); + CtrlDownDelay = CtrlDelay; //hunter-101012: jesli nie ma SCDDelay; + getkeyval( CtrlDownDelay, "SCDDelay", line, "" ); + + //hunter-111012: dla siodemek 303E + FastSerialCircuit = + ( extract_value( "FSCircuit", line ) == "Yes" ) ? + 1 : + 0; + + getkeyval( StopBrakeDecc, "SBD", line, "" ); +} + +void TMoverParameters::LoadFIZ_Light( std::string const &line ) { + + LightPowerSource.SourceType = LoadFIZ_SourceDecode( extract_value( "Light", line ) ); + LoadFIZ_PowerParamsDecode( LightPowerSource, "L", line ); + + AlterLightPowerSource.SourceType = LoadFIZ_SourceDecode( extract_value( "AlterLight", line ) ); + LoadFIZ_PowerParamsDecode( AlterLightPowerSource, "AlterL", line ); + + getkeyval( NominalVoltage, "Volt", line, "" ); + getkeyval( BatteryVoltage, "LMaxVoltage", line, "" ); + NominalBatteryVoltage = BatteryVoltage; +} + +void TMoverParameters::LoadFIZ_Security( std::string const &line ) { + + std::string awaresystem = extract_value( "AwareSystem", line ); + if( awaresystem.find( "Active" ) != std::string::npos ) { + SetFlag( SecuritySystem.SystemType, 1 ); + } + if( awaresystem.find( "CabSignal" ) != std::string::npos ) { + SetFlag( SecuritySystem.SystemType, 2 ); + } + + getkeyval( SecuritySystem.AwareDelay, "AwareDelay", line, "" ); + SecuritySystem.AwareMinSpeed = 0.1 * Vmax; //domyślnie 10% Vmax + getkeyval( SecuritySystem.AwareMinSpeed, "AwareMinSpeed", line, "" ); + getkeyval( SecuritySystem.SoundSignalDelay, "SoundSignalDelay", line, "" ); + getkeyval( SecuritySystem.EmergencyBrakeDelay, "EmergencyBrakeDelay", line, "" ); + SecuritySystem.RadioStop = ( extract_value( "RadioStop", line ).find( "Yes" ) != std::string::npos ); +} + +void TMoverParameters::LoadFIZ_Clima( std::string const &line ) { + + HeatingPowerSource.SourceType = LoadFIZ_SourceDecode( extract_value( "Heating", line ) ); + LoadFIZ_PowerParamsDecode( HeatingPowerSource, "H", line ); + AlterHeatPowerSource.SourceType = LoadFIZ_SourceDecode( extract_value( "AlterHeating", line ) ); + LoadFIZ_PowerParamsDecode( AlterHeatPowerSource, "AlterH", line ); +} + +void TMoverParameters::LoadFIZ_Power( std::string const &Line ) { + + EnginePowerSource.SourceType = LoadFIZ_SourceDecode( extract_value( "EnginePower", Line ) ); + LoadFIZ_PowerParamsDecode( EnginePowerSource, "", Line ); + + if( ( EnginePowerSource.SourceType == Generator ) + && ( EnginePowerSource.GeneratorEngine == WheelsDriven ) ) { + // perpetuum mobile? + ConversionError = 666; + } + if( Power == 0.0 ) { + //jeśli nie ma mocy, np. rozrządcze EZT + EnginePowerSource.SourceType = NotDefined; + } + + SystemPowerSource.SourceType = LoadFIZ_SourceDecode( extract_value( "SystemPower", Line ) ); + LoadFIZ_PowerParamsDecode( SystemPowerSource, "", Line ); +} + +void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) { + + EngineType = LoadFIZ_EngineDecode( extract_value( "EngineType", Input ) ); + + std::string transmission = extract_value( "Trans", Input ); + if( false == transmission.empty() ) { + // transmission type. moved here because more than one engine type has this entry + auto ratios = Split( transmission, ':' ); // e.g. 18:79 + + if( ratios.size() != 2 ) { + ErrorLog( "Wrong transmition definition: " + transmission ); + } + + Transmision.NToothM = std::atoi( ratios[0].c_str() ); // ToothM to pierwszy czyli 18 + Transmision.NToothW = std::atoi( ratios[1].c_str() ); // ToothW to drugi parametr czyli 79 + + if( Transmision.NToothM > 0 ) + Transmision.Ratio = static_cast( Transmision.NToothW ) / Transmision.NToothM; + else + Transmision.Ratio = 1.0; + } + + switch( EngineType ) { + + case ElectricSeriesMotor: { + + getkeyval( NominalVoltage, "Volt", Input, "" ); + getkeyval( WindingRes, "WindingRes", Input, "" ); + if( WindingRes == 0.0 ) { + + WindingRes = 0.01; + } + getkeyval( nmax, "nmax", Input, "" ); + nmax /= 60.0; + break; + } + case WheelsDriven: + case Dumb: { + + getkeyval( Ftmax, "Ftmax", Input, "" ); + break; + } + case DieselEngine: { + + getkeyval( dizel_nmin, "nmin", Input, "" ); + dizel_nmin /= 60.0; + getkeyval( dizel_nmax, "nmax", Input, "" ); + dizel_nmax /= 60.0; + nmax = dizel_nmax; // not sure if this is needed, but just in case + getkeyval( dizel_nmax_cutoff, "nmax_cutoff", Input, "0.0" ); + dizel_nmax_cutoff /= 60.0; + getkeyval( dizel_AIM, "AIM", Input, "1.0" ); + + if( true == getkeyval( AnPos, "ShuntMode", Input, "" ) ) { + //dodatkowa przekładnia dla SM03 (2Ls150) + ShuntModeAllow = true; + ShuntMode = false; + if( AnPos < 1.0 ) { + //"rozruch wysoki" ma dawać większą siłę + AnPos = 1.0 / AnPos; //im większa liczba, tym wolniej jedzie + } + } + break; + } + case DieselElectric: { //youBy + + getkeyval( Ftmax, "Ftmax", Input, "" ); + Flat = ( extract_value( "Flat", Input ) == "1" ); + getkeyval( Vhyp, "Vhyp", Input, "" ); + Vhyp /= 3.6; + getkeyval( Vadd, "Vadd", Input, "" ); + Vadd /= 3.6; + getkeyval( PowerCorRatio, "Cr", Input, "" ); + getkeyval( RelayType, "RelayType", Input, "" ); + if( extract_value( "ShuntMode", Input ) == "1" ) { + + ShuntModeAllow = true; + ShuntMode = false; + AnPos = 0.0; + ImaxHi = 2; + ImaxLo = 1; + } + break; + } + case ElectricInductionMotor: { + + RVentnmax = 1.0; + getkeyval( NominalVoltage, "Volt", Input, "" ); + + getkeyval( eimc[ eimc_s_dfic ], "dfic", Input, "" ); + getkeyval( eimc[ eimc_s_dfmax ], "dfmax", Input, "" ); + getkeyval( eimc[ eimc_s_p ], "p", Input, "" ); + getkeyval( eimc[ eimc_s_cfu ], "cfu", Input, "" ); + getkeyval( eimc[ eimc_s_cim ], "cim", Input, "" ); + getkeyval( eimc[ eimc_s_icif ], "icif", Input, "" ); + getkeyval( eimc[ eimc_f_Uzmax ], "Uzmax", Input, "" ); + getkeyval( eimc[ eimc_f_Uzh ], "Uzh", Input, "" ); + getkeyval( eimc[ eimc_f_DU ], "DU", Input, "" ); + getkeyval( eimc[ eimc_f_I0 ], "I0", Input, "" ); + getkeyval( eimc[ eimc_f_cfu ], "fcfu", Input, "" ); + getkeyval( eimc[ eimc_p_F0 ], "F0", Input, "" ); + getkeyval( eimc[ eimc_p_a1 ], "a1", Input, "" ); + getkeyval( eimc[ eimc_p_Pmax ], "Pmax", Input, "" ); + getkeyval( eimc[ eimc_p_Fh ], "Fh", Input, "" ); + getkeyval( eimc[ eimc_p_Ph ], "Ph", Input, "" ); + getkeyval( eimc[ eimc_p_Vh0 ], "Vh0", Input, "" ); + getkeyval( eimc[ eimc_p_Vh1 ], "Vh1", Input, "" ); + getkeyval( eimc[ eimc_p_Imax ], "Imax", Input, "" ); + getkeyval( eimc[ eimc_p_abed ], "abed", Input, "" ); + getkeyval( eimc[ eimc_p_eped ], "edep", Input, "" ); + + Flat = ( extract_value( "Flat", Input ) == "1" ); + + break; + } + default: { + // nothing here + } + } +} + +void TMoverParameters::LoadFIZ_Switches( std::string const &Input ) { + + getkeyval( PantSwitchType, "Pantograph", Input, "" ); + getkeyval( ConvSwitchType, "Converter", Input, "" ); +} + +void TMoverParameters::LoadFIZ_MotorParamTable( std::string const &Input ) { + + switch( EngineType ) { + + case DieselEngine: { + + getkeyval( dizel_minVelfullengage, "minVelfullengage", Input, "" ); + getkeyval( dizel_engageDia, "engageDia", Input, "" ); + getkeyval( dizel_engageMaxForce, "engageMaxForce", Input, "" ); + getkeyval( dizel_engagefriction, "engagefriction", Input, "" ); + break; + } + default: { + // nothing here + } + } +} + +void TMoverParameters::LoadFIZ_Circuit( std::string const &Input ) { + + getkeyval( CircuitRes, "CircuitRes", Input, "" ); + getkeyval( IminLo, "IminLo", Input, "" ); + getkeyval( IminHi, "IminHi", Input, "" ); + getkeyval( ImaxLo, "ImaxLo", Input, "" ); + getkeyval( ImaxHi, "ImaxHi", Input, "" ); + Imin = IminLo; + Imax = ImaxLo; +} + +void TMoverParameters::LoadFIZ_RList( std::string const &Input ) { + + auto const venttype = extract_value( "RVent", Input ); + if( venttype == "Automatic" ) { + + RVentType = 2; + } + else { + + RVentType = + venttype == "Yes" ? + 1 : + 0; + } + + if( RVentType > 0 ) { + + getkeyval( RVentnmax, "RVentmax", Input, "" ); + RVentnmax /= 60.0; + getkeyval( RVentCutOff, "RVentCutOff", Input, "" ); + } +} + +void TMoverParameters::LoadFIZ_DList( std::string const &Input ) { + + getkeyval( dizel_Mmax, "Mmax", Input, "" ); + getkeyval( dizel_nMmax, "nMmax", Input, "" ); + getkeyval( dizel_Mnmax, "Mnmax", Input, "" ); + getkeyval( dizel_nmax, "nmax", Input, "" ); + getkeyval( dizel_nominalfill, "nominalfill", Input, "" ); + getkeyval( dizel_Mstand, "Mstand", Input, "" ); +} + +void TMoverParameters::LoadFIZ_LightsList( std::string const &Input ) { + + getkeyval( LightsPosNo, "Size", Input, "" ); + getkeyval( LightsWrap, "Wrap", Input, "" ); + getkeyval( LightsDefPos, "Default", Input, "" ); +} + +void TMoverParameters::LoadFIZ_PowerParamsDecode( TPowerParameters &Powerparameters, std::string const Prefix, std::string const &Line ) { + + switch( Powerparameters.SourceType ) { + + case NotDefined: + case InternalSource: { + + Powerparameters.PowerType = LoadFIZ_PowerDecode( extract_value( Prefix + "PowerType", Line ) ); + break; + } + case Transducer: { + + getkeyval( Powerparameters.InputVoltage, Prefix + "TransducerInputV", Line, "" ); + break; + } + case Generator: { + + Powerparameters.GeneratorEngine = LoadFIZ_EngineDecode( extract_value( Prefix + "GeneratorEngine", Line ) ); + break; + } + case Accumulator: { + + getkeyval( Powerparameters.RAccumulator.MaxCapacity, Prefix + "Cap", Line, "" ); + Powerparameters.RAccumulator.RechargeSource = LoadFIZ_SourceDecode( extract_value( Prefix + "RS", Line ) ); + break; + } + case CurrentCollector: { + + auto &collectorparameters = Powerparameters.CollectorParameters; + + getkeyval( collectorparameters.CollectorsNo, "CollectorsNo", Line, "" ); + getkeyval( collectorparameters.MinH, "MinH", Line, "" ); + getkeyval( collectorparameters.MaxH, "MaxH", Line, "" ); + getkeyval( collectorparameters.CSW, "CSW", Line, "" ); //szerokość części roboczej + getkeyval( collectorparameters.MaxV, "MaxVoltage", Line, "" ); + collectorparameters.OVP = //przekaźnik nadnapięciowy + extract_value( "OverVoltProt", Line ) == "Yes" ? + 1 : + 0; + //napięcie rozłączające WS + collectorparameters.MinV = 0.5 * collectorparameters.MaxV; //gdyby parametr nie podany + getkeyval( collectorparameters.MinV, "MinV", Line, "" ); + //napięcie wymagane do załączenia WS + collectorparameters.InsetV = 0.6 * collectorparameters.MaxV; //gdyby parametr nie podany + getkeyval( collectorparameters.InsetV, "InsetV", Line, "" ); + //ciśnienie rozłączające WS + getkeyval( collectorparameters.MinPress, "MinPress", Line, "2.0" ); //domyślnie 2 bary do załączenia WS + //maksymalne ciśnienie za reduktorem + collectorparameters.MaxPress = 5.0 + 0.001 * ( Random( 50 ) - Random( 50 ) ); + getkeyval( collectorparameters.MaxPress, "MaxPress", Line, "" ); + break; + } + case PowerCable: { + + Powerparameters.RPowerCable.PowerTrans = LoadFIZ_PowerDecode( extract_value( Prefix + "PowerTrans", Line ) ); + if( Powerparameters.RPowerCable.PowerTrans == SteamPower ) { + + getkeyval( Powerparameters.RPowerCable.SteamPressure, Prefix + "SteamPress", Line, "" ); + } + break; + } + case Heater: { + //jeszcze nie skonczone! + break; + } + default: + ; // nothing here + } + + if( ( Powerparameters.SourceType != Heater ) + && ( Powerparameters.SourceType != InternalSource ) ) { + + + getkeyval( Powerparameters.MaxVoltage, Prefix + "MaxVoltage", Line, "" ); + getkeyval( Powerparameters.MaxCurrent, Prefix + "MaxCurrent", Line, "" ); + getkeyval( Powerparameters.IntR, Prefix + "IntR", Line, "" ); + } +} + +TPowerType TMoverParameters::LoadFIZ_PowerDecode( std::string const &Power ) { + + std::map powertypes{ + { "BioPower", BioPower }, + { "MechPower", MechPower }, + { "ElectricPower", ElectricPower }, + { "SteamPower", SteamPower } + }; + auto lookup = powertypes.find( Power ); + return + lookup != powertypes.end() ? + lookup->second : + NoPower; +} + +TPowerSource TMoverParameters::LoadFIZ_SourceDecode( std::string const &Source ) { + + std::map powersources{ + { "Transducer", Transducer }, + { "Generator", Generator }, + { "Accu", Accumulator }, + { "CurrentCollector", CurrentCollector }, + { "PowerCable", PowerCable }, + { "Heater", Heater }, + { "Internal", InternalSource } + }; + auto lookup = powersources.find( Source ); + return + lookup != powersources.end() ? + lookup->second : + NotDefined; +} + +TEngineTypes TMoverParameters::LoadFIZ_EngineDecode( std::string const &Engine ) { + + std::map enginetypes{ + { "ElectricSeriesMotor", ElectricSeriesMotor }, + { "DieselEngine", DieselEngine }, + { "SteamEngine", SteamEngine }, + { "WheelsDriven", WheelsDriven }, + { "Dumb", Dumb }, + { "DieselElectric", DieselElectric }, + { "DumbDE", DieselElectric }, + { "ElectricInductionMotor", ElectricInductionMotor } + }; + auto lookup = enginetypes.find( Engine ); + return + lookup != enginetypes.end() ? + lookup->second : + None; +} + // ************************************************************************************************* // Q: 20160717 // ************************************************************************************************* @@ -7372,29 +7092,245 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir) // WriteLog("aa = " + AxleArangement + " " + std::string( Pos("o", AxleArangement)) ); - if ((Pos("o", AxleArangement) > 0) && (EngineType == ElectricSeriesMotor)) - OK = ((RList[1].Bn * RList[1].Mn) == - NPoweredAxles); // test poprawnosci ilosci osi indywidualnie napedzanych - // WriteLogSS("aa ok", BoolToYN(OK)); + if( ( AxleArangement.find( "o" ) != std::string::npos ) && ( EngineType == ElectricSeriesMotor ) ) { + // test poprawnosci ilosci osi indywidualnie napedzanych + OK = ( ( RList[ 1 ].Bn * RList[ 1 ].Mn ) == NPoweredAxles ); + // WriteLogSS("aa ok", BoolToYN(OK)); + } + + if( ( LoadType.empty() == false ) && ( LoadAccepted.find( LoadType ) == std::string::npos ) ) { + // remove load if the type isn't supported + Load = 0.0; + } if (BrakeSystem == Individual) if (BrakeSubsystem != ss_None) OK = false; //! - if ((BrakeVVolume == 0) && (MaxBrakePress[3] > 0) && (BrakeSystem != Individual)) - BrakeVVolume = MaxBrakePress[3] / (5.0 - MaxBrakePress[3]) * - (BrakeCylRadius * BrakeCylRadius * BrakeCylDist * BrakeCylNo * PI) * 1000; - if (BrakeVVolume == 0) - BrakeVVolume = 0.01; - + if( ( BrakeVVolume == 0 ) && ( MaxBrakePress[ 3 ] > 0 ) && ( BrakeSystem != Individual ) ) { + BrakeVVolume = + MaxBrakePress[ 3 ] / + ( 5.0 - MaxBrakePress[ 3 ] ) * ( BrakeCylRadius * BrakeCylRadius * BrakeCylDist * BrakeCylNo * M_PI ) * 1000; + } + if( BrakeVVolume == 0.0 ) { + BrakeVVolume = 0.01; + } // WriteLog("BVV = " + FloatToStr(BrakeVVolume)); - if ((TestFlag(BrakeDelays, bdelay_G)) && - ((!TestFlag(BrakeDelays, bdelay_R)) || - (Power > 1))) // ustalanie srednicy przewodu glownego (lokomotywa lub napędowy + + switch( BrakeValve ) { + case W: + case K: + { + WriteLog( "XBT W, K" ); + Hamulec = std::make_shared( MaxBrakePress[ 3 ], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA ); + if( MBPM < 2 ) // jesli przystawka wazaca + Hamulec->SetLP( 0, MaxBrakePress[ 3 ], 0 ); + else + Hamulec->SetLP( Mass, MBPM, MaxBrakePress[ 1 ] ); + break; + } + case KE: + { + WriteLog( "XBT WKE" ); + Hamulec = std::make_shared( MaxBrakePress[ 3 ], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA ); + Hamulec->SetRM( RapidMult ); + if( MBPM < 2 ) // jesli przystawka wazaca + Hamulec->SetLP( 0, MaxBrakePress[ 3 ], 0 ); + else + Hamulec->SetLP( Mass, MBPM, MaxBrakePress[ 1 ] ); + break; + } + case NESt3: + case ESt3: + case ESt3AL2: + case ESt4: + { + WriteLog( "XBT NESt3, ESt3, ESt3AL2, ESt4" ); + Hamulec = std::make_shared( MaxBrakePress[ 3 ], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA ); + static_cast( Hamulec.get() )->SetSize( BrakeValveSize, BrakeValveParams ); + if( MBPM < 2 ) // jesli przystawka wazaca + Hamulec->SetLP( 0, MaxBrakePress[ 3 ], 0 ); + else + Hamulec->SetLP( Mass, MBPM, MaxBrakePress[ 1 ] ); + break; + } + case LSt: + { + WriteLog( "XBT LSt" ); + Hamulec = std::make_shared( MaxBrakePress[ 3 ], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA ); + Hamulec->SetRM( RapidMult ); + break; + } + case EStED: + { + WriteLog( "XBT EStED" ); + Hamulec = std::make_shared( MaxBrakePress[ 3 ], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA ); + Hamulec->SetRM( RapidMult ); + if( MBPM < 2 ) { + //jesli przystawka wazaca + Hamulec->SetLP( 0, MaxBrakePress[ 3 ], 0 ); + } + else { + Hamulec->SetLP( Mass, MBPM, MaxBrakePress[ 1 ] ); + } + break; + } + case EP2: + { + WriteLog( "XBT EP2" ); + Hamulec = std::make_shared( MaxBrakePress[ 3 ], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA ); + Hamulec->SetLP( Mass, MBPM, MaxBrakePress[ 1 ] ); + break; + } + case CV1: + { + WriteLog( "XBT CV1" ); + Hamulec = std::make_shared( MaxBrakePress[ 3 ], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA ); + break; + } + case CV1_L_TR: + { + WriteLog( "XBT CV1_L_T" ); + Hamulec = std::make_shared( MaxBrakePress[ 3 ], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA ); + break; + } + default: + Hamulec = std::make_shared( MaxBrakePress[ 3 ], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA ); + } + + Hamulec->SetASBP( MaxBrakePress[ 4 ] ); + + switch( BrakeHandle ) { + case FV4a: + Handle = std::make_shared(); + break; + case MHZ_EN57: + Handle = std::make_shared(); + break; + case FVel6: + Handle = std::make_shared(); + break; + case testH: + Handle = std::make_shared(); + break; + case M394: + Handle = std::make_shared(); + break; + case Knorr: + Handle = std::make_shared(); + break; + case St113: + Handle = std::make_shared(); + break; + default: + Handle = std::make_shared(); + } + + switch( BrakeLocHandle ) { + case FD1: + { + LocHandle = std::make_shared(); + LocHandle->Init( MaxBrakePress[ 0 ] ); + if( TrainType == dt_EZT ) { + + dynamic_cast(LocHandle.get())->SetSpeed( 3.5 ); + } + break; + } + case Knorr: + { + LocHandle = std::make_shared(); + LocHandle->Init( MaxBrakePress[ 0 ] ); + break; + } + default: + LocHandle = std::make_shared(); + } + + if ( ( true == TestFlag( BrakeDelays, bdelay_G ) ) + && ( false == TestFlag(BrakeDelays, bdelay_R) ) + || ( Power > 1.0 ) ) // ustalanie srednicy przewodu glownego (lokomotywa lub napędowy Spg = 0.792; else Spg = 0.507; + // WriteLog("SPG = " + FloatToStr(Spg)); + + Pipe = std::make_shared(); + Pipe2 = std::make_shared(); // zabezpieczenie, bo sie PG wywala... :( + Pipe->CreateCap( ( std::max( Dim.L, 14.0 ) + 0.5 ) * Spg * 1 ); // dlugosc x przekroj x odejscia i takie tam + Pipe2->CreateCap( ( std::max( Dim.L, 14.0 ) + 0.5 ) * Spg * 1 ); + + if( LightsPosNo > 0 ) + LightsPos = LightsDefPos; + + // checking ready flag + // to dac potem do init + if( ReadyFlag ) // gotowy do drogi + { + WriteLog( "Ready to depart" ); + CompressedVolume = VeselVolume * MinCompressor * ( 9.8 ) / 10.0; + ScndPipePress = CompressedVolume / VeselVolume; + PipePress = CntrlPipePress; + BrakePress = 0.0; + LocalBrakePos = 0.0; + if( CabNo == 0 ) + BrakeCtrlPos = static_cast( Handle->GetPos( bh_NP ) ); + else + BrakeCtrlPos = static_cast( Handle->GetPos( bh_RP ) ); + MainSwitch( false ); + PantFront( true ); + PantRear( true ); + MainSwitch( true ); + ActiveDir = 0; // Dir; //nastawnik kierunkowy - musi być ustawiane osobno! + DirAbsolute = ActiveDir * CabNo; // kierunek jazdy względem sprzęgów + LimPipePress = CntrlPipePress; + } + else { // zahamowany} + WriteLog( "Braked" ); + Volume = BrakeVVolume * MaxBrakePress[ 3 ]; + CompressedVolume = VeselVolume * MinCompressor * 0.55; + ScndPipePress = 5.1; + PipePress = LowPipePress; + PipeBrakePress = MaxBrakePress[ 3 ] * 0.5; + BrakePress = MaxBrakePress[ 3 ] * 0.5; + LocalBrakePos = 0; + BrakeCtrlPos = static_cast( Handle->GetPos( bh_NP ) ); + LimPipePress = LowPipePress; + } + + ActFlowSpeed = 0.0; + BrakeCtrlPosR = BrakeCtrlPos; + + if( BrakeLocHandle == Knorr ) + LocalBrakePos = 5; + + Pipe->CreatePress( PipePress ); + Pipe2->CreatePress( ScndPipePress ); + Pipe->Act(); + Pipe2->Act(); + + EqvtPipePress = PipePress; + + Handle->Init( PipePress ); + + ComputeConstans(); + + if( LoadFlag > 0 ) { + + if( Load < MaxLoad * 0.45 ) { + IncBrakeMult(); + IncBrakeMult(); + DecBrakeMult(); // TODO: przeinesiono do mover.cpp + if( Load < MaxLoad * 0.35 ) + DecBrakeMult(); + } + else { + IncBrakeMult(); // TODO: przeinesiono do mover.cpp + if( Load >= MaxLoad * 0.55 ) + IncBrakeMult(); + } + } // taki mini automat - powinno byc ladnie dobrze :) BrakeDelayFlag = bdelay_P; @@ -7403,230 +7339,21 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir) if ((TestFlag(BrakeDelays, bdelay_R)) && !(TestFlag(BrakeDelays, bdelay_G))) BrakeDelayFlag = bdelay_R; - int DefBrakeTable[8] = { 15, 4, 25, 25, 13, 3, 12, 2 }; - - if (LoadFlag > 0) - { - if (Load < MaxLoad * 0.45) - { - IncBrakeMult(); - IncBrakeMult(); - DecBrakeMult(); // TODO: przeinesiono do mover.cpp - if (Load < MaxLoad * 0.35) - DecBrakeMult(); - } - if (Load >= MaxLoad * 0.45) - { - IncBrakeMult(); // TODO: przeinesiono do mover.cpp - if (Load >= MaxLoad * 0.55) - IncBrakeMult(); - } - } - if (BrakeOpModes & bom_PS) BrakeOpModeFlag = bom_PS; else BrakeOpModeFlag = bom_PN; // yB: jesli pojazdy nie maja zadeklarowanych czasow, to wsadz z przepisow +-16,(6)% - for (b = 1; b < 4; b++) + int DefBrakeTable[8] = { 15, 4, 25, 25, 13, 3, 12, 2 }; + + for( b = 1; b < 4; b++ ) { if (BrakeDelay[b] == 0) BrakeDelay[b] = DefBrakeTable[b]; BrakeDelay[b] = BrakeDelay[b] * (2.5 + Random(0.0, 0.2)) / 3.0; } - // WriteLog("SPG = " + FloatToStr(Spg)); - - switch (BrakeValve) - { - case W: - case K: - { - WriteLog("XBT W, K"); - Hamulec = std::make_shared(MaxBrakePress[3], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA); - if (MBPM < 2) // jesli przystawka wazaca - Hamulec->SetLP(0, MaxBrakePress[3], 0); - else - Hamulec->SetLP(Mass, MBPM, MaxBrakePress[1]); - break; - } - case KE: - { - WriteLog("XBT WKE"); - Hamulec = std::make_shared(MaxBrakePress[3], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA); - Hamulec->SetRM(RapidMult); - if (MBPM < 2) // jesli przystawka wazaca - Hamulec->SetLP(0, MaxBrakePress[3], 0); - else - Hamulec->SetLP(Mass, MBPM, MaxBrakePress[1]); - break; - } - case NESt3: - case ESt3: - case ESt3AL2: - case ESt4: - { - WriteLog("XBT NESt3, ESt3, ESt3AL2, ESt4"); - Hamulec = std::make_shared(MaxBrakePress[3], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA); - static_cast(Hamulec.get())->SetSize(BrakeValveSize, BrakeValveParams); - if (MBPM < 2) // jesli przystawka wazaca - Hamulec->SetLP(0, MaxBrakePress[3], 0); - else - Hamulec->SetLP(Mass, MBPM, MaxBrakePress[1]); - break; - } - - case LSt: - { - WriteLog("XBT LSt"); - Hamulec = std::make_shared(MaxBrakePress[3], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA); - Hamulec->SetRM(RapidMult); - break; - } - case EStED: - { - WriteLog("XBT EStED"); - Hamulec = std::make_shared(MaxBrakePress[3], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA); - Hamulec->SetRM(RapidMult); - if( MBPM < 2 ) { - //jesli przystawka wazaca - Hamulec->SetLP( 0, MaxBrakePress[ 3 ], 0 ); - } - else { - Hamulec->SetLP( Mass, MBPM, MaxBrakePress[ 1 ] ); - } - break; - } - case EP2: - { - WriteLog("XBT EP2"); - Hamulec = std::make_shared(MaxBrakePress[3], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA); - Hamulec->SetLP(Mass, MBPM, MaxBrakePress[1]); - break; - } - - case CV1: - { - WriteLog("XBT CV1"); - Hamulec = std::make_shared(MaxBrakePress[3], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA); - break; - } - case CV1_L_TR: - { - WriteLog("XBT CV1_L_T"); - Hamulec = std::make_shared(MaxBrakePress[3], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA); - break; - } - - default: - Hamulec = std::make_shared(MaxBrakePress[3], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA); - } - - Hamulec->SetASBP(MaxBrakePress[4]); - - switch (BrakeHandle) - { - case FV4a: - Handle = std::make_shared(); - break; - case FVel6: - Handle = std::make_shared(); - break; - case testH: - Handle = std::make_shared(); - break; - case M394: - Handle = std::make_shared(); - break; - case Knorr: - Handle = std::make_shared(); - break; - case St113: - Handle = std::make_shared(); - break; - default: - Handle = std::make_shared(); - } - - switch (BrakeLocHandle) - { - case FD1: - { - LocHandle = std::make_shared(); - LocHandle->Init(MaxBrakePress[0]); - break; - } - case Knorr: - { - LocHandle = std::make_shared(); - LocHandle->Init(MaxBrakePress[0]); - break; - } - default: - LocHandle = std::make_shared(); - } - - Pipe = std::make_shared(); - Pipe->CreateCap( ( Max0R( Dim.L, 14 ) + 0.5 ) * Spg * 1 ); // dlugosc x przekroj x odejscia i takie tam - Pipe2 = std::make_shared(); // zabezpieczenie, bo sie PG wywala... :( - Pipe2->CreateCap( (Max0R(Dim.L, 14) + 0.5) * Spg * 1 ); - - if (LightsPosNo > 0) - LightsPos = LightsDefPos; - - // checking ready flag - // to dac potem do init - if (ReadyFlag) // gotowy do drogi - { - WriteLog("Ready to depart"); - CompressedVolume = VeselVolume * MinCompressor * (9.8) / 10; - ScndPipePress = CompressedVolume / VeselVolume; - PipePress = CntrlPipePress; - BrakePress = 0; - LocalBrakePos = 0; - if (CabNo == 0) - BrakeCtrlPos = Handle->GetPos(bh_NP); - else - BrakeCtrlPos = Handle->GetPos(bh_RP); - MainSwitch(false); - PantFront(true); - PantRear(true); - MainSwitch(true); - ActiveDir = 0; // Dir; //nastawnik kierunkowy - musi być ustawiane osobno! - DirAbsolute = ActiveDir * CabNo; // kierunek jazdy względem sprzęgów - LimPipePress = CntrlPipePress; - } - else - { // zahamowany} - WriteLog("Braked"); - Volume = BrakeVVolume * MaxBrakePress[3]; - CompressedVolume = VeselVolume * MinCompressor * 0.55; - ScndPipePress = 5.1; - PipePress = LowPipePress; - PipeBrakePress = MaxBrakePress[3] / 2; - BrakePress = MaxBrakePress[3] / 2; - LocalBrakePos = 0; - LimPipePress = LowPipePress; - } - - ActFlowSpeed = 0; - BrakeCtrlPosR = BrakeCtrlPos; - - if (BrakeLocHandle == Knorr) - LocalBrakePos = 5; - - Pipe->CreatePress(PipePress); - Pipe2->CreatePress(ScndPipePress); - Pipe->Act(); - Pipe2->Act(); - - EqvtPipePress = PipePress; - - Handle->Init(PipePress); - - ComputeConstans(); - if (TrainType == dt_ET22) CompressorPower = 0; @@ -7720,7 +7447,7 @@ bool TMoverParameters::SendCtrlToNext( std::string CtrlCommand, double ctrlvalue // Ra: był problem z propagacją, jeśli w składzie jest pojazd wstawiony odwrotnie // Ra: problem jest również, jeśli AI będzie na końcu składu OK = ( dir != 0 ); // and Mains; - d = ( 1 + Sign( dir ) ) / 2; // dir=-1=>d=0, dir=1=>d=1 - wysyłanie tylko w tył + d = ( 1 + static_cast(Sign( dir )) ) / 2; // dir=-1=>d=0, dir=1=>d=1 - wysyłanie tylko w tył if( OK ) { // musi być wybrana niezerowa kabina if( ( Couplers[ d ].Connected != nullptr ) @@ -7760,7 +7487,7 @@ bool TMoverParameters::RunCommand(std::string Command, double CValue1, double CV if (Command == "MainCtrl") { if (MainCtrlPosNo >= floor(CValue1)) - MainCtrlPos = floor(CValue1); + MainCtrlPos = static_cast(floor(CValue1)); OK = SendCtrlToNext(Command, CValue1, CValue2); } else if (Command == "ScndCtrl") @@ -7774,7 +7501,7 @@ bool TMoverParameters::RunCommand(std::string Command, double CValue1, double CV else if ((floor(CValue1) == 0)) ScndCtrlActualPos = 0; if (ScndCtrlPosNo >= floor(CValue1)) - ScndCtrlPos = floor(CValue1); + ScndCtrlPos = static_cast(floor(CValue1)); OK = SendCtrlToNext(Command, CValue1, CValue2); } /* else if command='BrakeCtrl' then @@ -7811,7 +7538,7 @@ bool TMoverParameters::RunCommand(std::string Command, double CValue1, double CV } else if (Command == "Direction") { - ActiveDir = floor(CValue1); + ActiveDir = static_cast(floor(CValue1)); DirAbsolute = ActiveDir * CabNo; OK = SendCtrlToNext(Command, CValue1, CValue2); } @@ -8028,9 +7755,9 @@ bool TMoverParameters::RunCommand(std::string Command, double CValue1, double CV else if (Command == "SetDamage") { if (CValue2 == 1) - OK = SetFlag(DamageFlag, floor(CValue1)); + OK = SetFlag(DamageFlag, static_cast(floor(CValue1))); if (CValue2 == -1) - OK = SetFlag(DamageFlag, -floor(CValue1)); + OK = SetFlag(DamageFlag, static_cast(-floor(CValue1))); } else if (Command == "Emergency_brake") { @@ -8041,7 +7768,7 @@ bool TMoverParameters::RunCommand(std::string Command, double CValue1, double CV } else if (Command == "BrakeDelay") { - BrakeDelayFlag = floor(CValue1); + BrakeDelayFlag = static_cast(floor(CValue1)); OK = true; } else if (Command == "SandDoseOn") @@ -8058,8 +7785,8 @@ bool TMoverParameters::RunCommand(std::string Command, double CValue1, double CV 2)) // jeśli kabina jest obsadzona (silnikowy w EZT?) /*?*/ /* WITH SecuritySystem */ { - SecuritySystem.VelocityAllowed = floor(CValue1); - SecuritySystem.NextVelocityAllowed = floor(CValue2); + SecuritySystem.VelocityAllowed = static_cast(floor(CValue1)); + SecuritySystem.NextVelocityAllowed = static_cast(floor(CValue2)); SecuritySystem.SystemSoundSHPTimer = 0; // hunter-091012 SetFlag(SecuritySystem.Status, s_active); } @@ -8129,7 +7856,7 @@ bool TMoverParameters::RunInternalCommand(void) // Q: 20160714 // Zwraca wartość natężenia prądu na wybranym amperomierzu. Podfunkcja do ShowCurrent. // ************************************************************************************************* -int TMoverParameters::ShowCurrentP(int AmpN) +double TMoverParameters::ShowCurrentP(int AmpN) { int b, Bn; bool Grupowy; @@ -8159,7 +7886,7 @@ int TMoverParameters::ShowCurrentP(int AmpN) // with Couplers[b] do if (TestFlag(Couplers[b].CouplingFlag, ctrain_controll)) if (Couplers[b].Connected->Power > 0.01) - current = Couplers[b].Connected->ShowCurrent(AmpN); + current = static_cast(Couplers[b].Connected->ShowCurrent(AmpN)); return current; } } diff --git a/McZapkie/hamulce.cpp b/McZapkie/hamulce.cpp index ba43daf4..47634153 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -51,16 +51,16 @@ double PF_old(double P1, double P2, double S) double PF(double P1, double P2, double S, double DP) { - double PH = Max0R(P1, P2) + 1; // wyzsze cisnienie absolutne + double PH = std::max(P1, P2) + 1; // wyzsze cisnienie absolutne double PL = P1 + P2 - PH + 2; // nizsze cisnienie absolutne double sg = PL / PH; // bezwymiarowy stosunek cisnien double FM = PH * 197 * S * Sign(P2 - P1); // najwyzszy mozliwy przeplyw, wraz z kierunkiem if ((sg > 0.5)) // jesli ponizej stosunku krytycznego if ((PH - PL) < DP) // niewielka roznica cisnien - return (1 - sg) / DPL * FM * 2 * sqrt((DP) * (PH - DP)); + return (1 - sg) / DPL * FM * 2 * std::sqrt((DP) * (PH - DP)); // return 1/DPL*(PH-PL)*fm*2*SQRT((sg)*(1-sg)); else - return FM * 2 * sqrt((sg) * (1 - sg)); + return FM * 2 * std::sqrt((sg) * (1 - sg)); else // powyzej stosunku krytycznego return FM; } @@ -69,15 +69,15 @@ double PF1(double P1, double P2, double S) { static double const DPS = 0.001; - double PH = Max0R(P1, P2) + 1; // wyzsze cisnienie absolutne + double PH = std::max(P1, P2) + 1; // wyzsze cisnienie absolutne double PL = P1 + P2 - PH + 2; // nizsze cisnienie absolutne double sg = PL / PH; // bezwymiarowy stosunek cisnien double FM = PH * 197 * S * Sign(P2 - P1); // najwyzszy mozliwy przeplyw, wraz z kierunkiem if ((sg > 0.5)) // jesli ponizej stosunku krytycznego if ((sg < DPS)) // niewielka roznica cisnien - return (1 - sg) / DPS * FM * 2 * sqrt((DPS) * (1 - DPS)); + return (1 - sg) / DPS * FM * 2 * std::sqrt((DPS) * (1 - DPS)); else - return FM * 2 * sqrt((sg) * (1 - sg)); + return FM * 2 * std::sqrt((sg) * (1 - sg)); else // powyzej stosunku krytycznego return FM; } @@ -96,9 +96,9 @@ double PFVa(double PH, double PL, double S, double LIM, FM = FM * (LIM - PL) / DP; // jesli jestesmy przy nastawieniu, to zawor sie przymyka if ((sg > 0.5)) // jesli ponizej stosunku krytycznego if ((PH - PL) < DPL) // niewielka roznica cisnien - return (PH - PL) / DPL * FM * 2 * sqrt((sg) * (1 - sg)); // BUG: (1-sg) can be < 0, leading to sqrt(-x) + return (PH - PL) / DPL * FM * 2 * std::sqrt((sg) * (1 - sg)); // BUG: (1-sg) can be < 0, leading to sqrt(-x) else - return FM * 2 * sqrt( (sg) * ( 1 - sg ) ); // BUG: (1-sg) can be < 0, leading to sqrt(-x) + return FM * 2 * std::sqrt( (sg) * ( 1 - sg ) ); // BUG: (1-sg) can be < 0, leading to sqrt(-x) else // powyzej stosunku krytycznego return FM; } @@ -120,9 +120,9 @@ double PFVd(double PH, double PL, double S, double LIM, FM = FM * (PH - LIM) / DP; // jesli jestesmy przy nastawieniu, to zawor sie przymyka if ((sg > 0.5)) // jesli ponizej stosunku krytycznego if ((PH - PL) < DPL) // niewielka roznica cisnien - return (PH - PL) / DPL * FM * 2 * sqrt((sg) * (1 - sg)); + return (PH - PL) / DPL * FM * 2 * std::sqrt((sg) * (1 - sg)); else - return FM * 2 * sqrt((sg) * (1 - sg)); + return FM * 2 * std::sqrt((sg) * (1 - sg)); else // powyzej stosunku krytycznego return FM; } @@ -2749,8 +2749,8 @@ double TFD1::GetPF(double i_bcp, double PP, double HP, double dt, double ep) // MaxBP:=4; // temp:=Min0R(i_bcp*MaxBP,Min0R(5.0,HP)); - temp = Min0R(i_bcp * MaxBP, HP); // 0011 - DP = 10 * Min0R(abs(temp - BP), 0.1) * PF(temp, BP, 0.0006 * (2 + int(temp > BP))) * dt * Speed; + temp = std::min(i_bcp * MaxBP, HP); // 0011 + DP = 10.0 * std::min(std::abs(temp - BP), 0.1) * PF(temp, BP, 0.0006 * (temp > BP ? 3.0 : 2.0) ) * dt * Speed; BP = BP - DP; return -DP; } diff --git a/Names.h b/Names.h index 50b85da7..e0bb33d1 100644 --- a/Names.h +++ b/Names.h @@ -1,3 +1,4 @@ +#pragma once /* This Source Code Form is subject to the terms of the Mozilla Public License, v. @@ -7,8 +8,64 @@ obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef NamesH -#define NamesH +#include +#include + +template +class TNames { + +public: +// types: + +// constructors: + TNames() = default; + +// destructor: + +// methods: + // dodanie obiektu z wskaźnikiem. updates data field if the object already exists. returns true for insertion, false for update + bool + Add( int const Type, std::string const &Name, _Pointer Data ) { + + auto lookup = find_map( Type ).emplace( Name, Data ); + if( lookup.second == false ) { + // record already exists, update it + lookup.first->second = Data; + return false; + } + else { + // new record inserted, bail out + return true; + } + } + // returns pointer associated with provided label, or nullptr if there's no match + _Pointer + Find( int const Type, std::string const &Name ) { + + auto const &map = find_map( Type ); + auto const lookup = map.find( Name ); + if( lookup != map.end() ) { return lookup->second; } + else { return nullptr; } + } + +private: +// types: + typedef std::unordered_map pointer_map; + typedef std::unordered_map pointermap_map; + +// methods: + // returns database stored with specified type key; creates new database if needed. + pointer_map & + find_map( int const Type ) { + + return m_maps.emplace( Type, pointer_map() ).first->second; + } + +// members: + pointermap_map m_maps; // list of pointer maps of types specified so far +}; + +#ifdef EU07_USE_OLD_TNAMES_CLASS //--------------------------------------------------------------------------- class ItemRecord { // rekord opisujący obiekt; raz utworzony nie przemieszcza się diff --git a/Spring.cpp b/Spring.cpp index 525c4c03..38104815 100644 --- a/Spring.cpp +++ b/Spring.cpp @@ -29,7 +29,7 @@ void TSpring::Init(double nrestLen, double nKs, double nKd) restLen = nrestLen; } -bool TSpring::ComputateForces(vector3 pPosition1, vector3 pPosition2) +Math3D::vector3 TSpring::ComputateForces(vector3 const &pPosition1, vector3 const &pPosition2) { double dist, Hterm, Dterm; @@ -41,31 +41,29 @@ bool TSpring::ComputateForces(vector3 pPosition1, vector3 pPosition2) // dist = VectorLength(&deltaP); // Magnitude of // deltaP dist = deltaP.Length(); - if (dist == 0) - { - vForce1 = vForce2 = vector3(0, 0, 0); - return false; + if (dist != 0.0 ) { + + // Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest) + Hterm = ( dist - restLen ) * Ks; // Ks * (dist - rest) + + // VectorDifference(&p1->v,&p2->v,&deltaV); // Delta Velocity Vector + deltaV = pPosition1 - pPosition2; + + // Dterm = (DotProduct(&deltaV,&deltaP) * spring->Kd) / dist; // Damping Term + // Dterm = (DotProduct(deltaV,deltaP) * Kd) / dist; + Dterm = 0; + + // ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector + // ScaleVector(&springForce,-(Hterm + Dterm),&springForce); // Calc Force + springForce = deltaP / dist * ( -( Hterm + Dterm ) ); + // VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 + // VectorDifference(&p2->f,&springForce,&p2->f); // - Force on Particle 2 } - // Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest) - Hterm = (dist - restLen) * Ks; // Ks * (dist - rest) - - // VectorDifference(&p1->v,&p2->v,&deltaV); // Delta Velocity Vector - deltaV = pPosition1 - pPosition2; - - // Dterm = (DotProduct(&deltaV,&deltaP) * spring->Kd) / dist; // Damping Term - // Dterm = (DotProduct(deltaV,deltaP) * Kd) / dist; - Dterm = 0; - - // ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector - // ScaleVector(&springForce,-(Hterm + Dterm),&springForce); // Calc Force - springForce = deltaP / dist * (-(Hterm + Dterm)); - // VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1 - // VectorDifference(&p2->f,&springForce,&p2->f); // - Force on Particle 2 vForce1 = springForce; vForce2 = springForce; - return true; + return springForce; } void TSpring::Render() diff --git a/Spring.h b/Spring.h index a215609d..e716b8b9 100644 --- a/Spring.h +++ b/Spring.h @@ -31,7 +31,7 @@ class TSpring // void Init(TParticnp1, TParticle *np2, double nKs= 0.5f, double nKd= 0.002f, // double nrestLen= -1.0f); void Init(double nrestLen, double nKs = 0.5f, double nKd = 0.002f); - bool ComputateForces(vector3 pPosition1, vector3 pPosition2); + Math3D::vector3 ComputateForces(vector3 const &pPosition1, vector3 const &pPosition2); void Render(); vector3 vForce1, vForce2; double restLen; // LENGTH OF SPRING AT REST diff --git a/Train.cpp b/Train.cpp index 4a86e602..9196e232 100644 --- a/Train.cpp +++ b/Train.cpp @@ -217,13 +217,13 @@ bool TTrain::Init(TDynamicObject *NewDynamicObject, bool e3d) } } */ - MechSpring.Init(0, 500); + MechSpring.Init(0.015, 250); vMechVelocity = vector3(0, 0, 0); pMechOffset = vector3(-0.4, 3.3, 5.5); fMechCroach = 0.5; fMechSpringX = 1; - fMechSpringY = 0.1; - fMechSpringZ = 0.1; + fMechSpringY = 0.5; + fMechSpringZ = 0.5; fMechMaxSpring = 0.15; fMechRoll = 0.05; fMechPitch = 0.1; @@ -2545,36 +2545,40 @@ void TTrain::UpdateMechPosition(double dt) // - przy szybkiej jeździe kabina prosto, horyzont pochylony vector3 pNewMechPosition; + Math3D::vector3 shake; // McZapkie: najpierw policzę pozycję w/m kabiny // ABu: rzucamy kabina tylko przy duzym FPS! // Mala histereza, zeby bez przerwy nie przelaczalo przy FPS~17 // Granice mozna ustalic doswiadczalnie. Ja proponuje 14:20 - double r1, r2, r3; - int iVel = DynamicObject->GetVelocity(); - if (iVel > 150) - iVel = 150; + double const iVel = std::min(DynamicObject->GetVelocity(), 150.0); + if (!Global::iSlowMotion // musi być pełna prędkość && (pMechOffset.y < 4.0)) // Ra 15-01: przy oglądaniu pantografu bujanie przeszkadza { - if (!(Random((GetFPS() + 1) / 15) > 0)) - { - if ((iVel > 0) && (Random(155 - iVel) < 16)) - { - r1 = (double(Random(iVel * 2) - iVel) / ((iVel * 2) * 4)) * fMechSpringX; - r2 = (double(Random(iVel * 2) - iVel) / ((iVel * 2) * 4)) * fMechSpringY; - r3 = (double(Random(iVel * 2) - iVel) / ((iVel * 2) * 4)) * fMechSpringZ; - MechSpring.ComputateForces(vector3(r1, r2, r3), pMechShake); - // MechSpring.ComputateForces(vector3(double(random(200)-100)/200,double(random(200)-100)/200,double(random(200)-100)/500),pMechShake); + if( iVel > 0.0 ) { + // acceleration-driven base shake + shake += 1.25 * MechSpring.ComputateForces( + vector3( + -mvControlled->AccN * dt * 5.0, // highlight side sway + mvControlled->AccV * dt, + -mvControlled->AccS * dt * 1.25 ), // accent acceleration/deceleration + pMechShake ); + + if( Random( iVel ) > 25.0 ) { + // extra shake at increased velocity + shake += MechSpring.ComputateForces( + vector3( + ( Random( iVel * 2 ) - iVel ) / ( ( iVel * 2 ) * 4 ) * fMechSpringX, + ( Random( iVel * 2 ) - iVel ) / ( ( iVel * 2 ) * 4 ) * fMechSpringY, + ( Random( iVel * 2 ) - iVel ) / ( ( iVel * 2 ) * 4 ) * fMechSpringZ ), + pMechShake ); +// * (( 200 - DynamicObject->MyTrack->iQualityFlag ) * 0.0075 ); // scale to 75-150% based on track quality } - else - MechSpring.ComputateForces(vector3(-mvControlled->AccN * dt, - mvControlled->AccV * dt * 10, - -mvControlled->AccS * dt), - pMechShake); +// shake *= 1.25; } - vMechVelocity -= (MechSpring.vForce2 + vMechVelocity * 100) * - (fMechSpringX + fMechSpringY + fMechSpringZ) / (200); + vMechVelocity -= (shake + vMechVelocity * 100) * (fMechSpringX + fMechSpringY + fMechSpringZ) / (200); +// shake *= 0.95 * dt; // shake damping // McZapkie: pMechShake += vMechVelocity * dt; @@ -2583,14 +2587,12 @@ void TTrain::UpdateMechPosition(double dt) if ((pMechShake.y > fMechMaxSpring) || (pMechShake.y < -fMechMaxSpring)) vMechVelocity.y = -vMechVelocity.y; // ABu011104: 5*pMechShake.y, zeby ladnie pudlem rzucalo :) - pNewMechPosition = pMechOffset + vector3(pMechShake.x, 5 * pMechShake.y, pMechShake.z); + pNewMechPosition = pMechOffset + vector3(1.5 * pMechShake.x, 2.0 * pMechShake.y, 1.5 * pMechShake.z); vMechMovement = 0.5 * vMechMovement; } else { // hamowanie rzucania przy spadku FPS - pMechShake -= pMechShake * Min0R(dt, 1); // po tym chyba potrafią zostać - // jakieś ułamki, które powodują - // zjazd + pMechShake -= pMechShake * std::min(dt, 1.0); // po tym chyba potrafią zostać jakieś ułamki, które powodują zjazd pMechOffset += vMechMovement * dt; vMechVelocity.y = 0.5 * vMechVelocity.y; pNewMechPosition = pMechOffset + vector3(pMechShake.x, 5 * pMechShake.y, pMechShake.z); @@ -5067,6 +5069,8 @@ bool TTrain::LoadMMediaFile(std::string const &asFileName) { double dSDist; cParser parser(asFileName, cParser::buffer_FILE); + // NOTE: yaml-style comments are disabled until conflict in use of # is resolved + // parser.addCommentStyle( "#", "\n" ); //Wartości domyślne by nie wysypywało przy wybrakowanych mmd @240816 Stele dsbPneumaticSwitch = TSoundsManager::GetFromName("silence1.wav", true); dsbBufferClamp = TSoundsManager::GetFromName("en57_bufferclamp.wav", true); @@ -5312,7 +5316,7 @@ bool TTrain::LoadMMediaFile(std::string const &asFileName) double ks, kd; parser.getTokens(2, false); parser >> ks >> kd; - MechSpring.Init(0, ks, kd); + MechSpring.Init(MechSpring.restLen, ks, kd); parser.getTokens(6, false); parser >> fMechSpringX >> fMechSpringY >> fMechSpringZ >> fMechMaxSpring >> fMechRoll >> fMechPitch; @@ -5388,6 +5392,8 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) std::string cabstr("cab" + std::to_string(cabindex) + "definition:"); std::shared_ptr parser = std::make_shared(asFileName, cParser::buffer_FILE); + // NOTE: yaml-style comments are disabled until conflict in use of # is resolved + // parser.addCommentStyle( "#", "\n" ); std::string token; do { @@ -5404,6 +5410,8 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) cabstr = "cab1definition:"; // crude way to start parsing from beginning parser = std::make_shared(asFileName, cParser::buffer_FILE); + // NOTE: yaml-style comments are disabled until conflict in use of # is resolved + // parser.addCommentStyle( "#", "\n" ); do { token = ""; diff --git a/World.cpp b/World.cpp index cd9065cb..6ebe9161 100644 --- a/World.cpp +++ b/World.cpp @@ -1930,16 +1930,11 @@ TWorld::Render_UI() { if( Global::iTextMode == VK_F1 ) { // tekst pokazywany po wciśnięciu [F1] // Global::iViewMode=VK_F1; glColor3f( 1.0f, 1.0f, 1.0f ); // a, damy białym - OutText1 = "Time: " + to_string( (int)GlobalTime->hh ) + ":"; - int i = GlobalTime->mm; // bo inaczej potrafi zrobić "hh:010" - if( i < 10 ) - OutText1 += "0"; - OutText1 += to_string( i ); // minuty - OutText1 += ":"; - i = floor( GlobalTime->mr ); // bo inaczej potrafi zrobić "hh:mm:010" - if( i < 10 ) - OutText1 += "0"; - OutText1 += to_string( i ); + OutText1 = + "Time: " + + to_string( (int)GlobalTime->hh ) + ":" + + ( GlobalTime->mm < 10 ? "0" : "" ) + to_string( GlobalTime->mm ) + ":" + + ( GlobalTime->mr < 10 ? "0" : "" ) + to_string( std::floor( GlobalTime->mr ) ); if( Global::iPause ) OutText1 += " - paused"; if( Controlled ) diff --git a/maszyna.vcxproj b/maszyna.vcxproj index 2eb00999..c0f7ee8a 100644 --- a/maszyna.vcxproj +++ b/maszyna.vcxproj @@ -114,7 +114,6 @@ - diff --git a/maszyna.vcxproj.filters b/maszyna.vcxproj.filters index c83a353f..d18b00e4 100644 --- a/maszyna.vcxproj.filters +++ b/maszyna.vcxproj.filters @@ -99,9 +99,6 @@ Source Files - - Source Files - Source Files diff --git a/mtable.cpp b/mtable.cpp index ee540e84..680f6cc6 100644 --- a/mtable.cpp +++ b/mtable.cpp @@ -59,7 +59,7 @@ double TTrainParameters::WatchMTable(double DistCounter) std::string TTrainParameters::NextStop() { // pobranie nazwy następnego miejsca zatrzymania if (StationIndex <= StationCount) - return "PassengerStopPoint:" + NextStationName; // nazwa następnego przystanku; + return NextStationName; // nazwa następnego przystanku; else return "[End of route]"; //że niby koniec } @@ -401,11 +401,14 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax) } while (s.find("|") == std::string::npos) fin >> s; - fin >> record->StationWare; - do - { + // stationware. added fix for empty entry + fin >> s; + while( false == ( ( s == "1" ) + || ( s == "2" ) + || fin.bad() ) ) { + record->StationWare += s; fin >> s; - } while (!((s == "1") || (s == "2") || fin.bad())); + } record->TrackNo = atoi(s.c_str()); fin >> s; if (s != "|") diff --git a/parser.cpp b/parser.cpp index 5cdc7ad7..46cd8701 100644 --- a/parser.cpp +++ b/parser.cpp @@ -21,9 +21,9 @@ http://mozilla.org/MPL/2.0/. // cParser -- generic class for parsing text data. // constructors -cParser::cParser(std::string const Stream, buffertype Type, std::string Path, bool tr) +cParser::cParser( std::string const &Stream, buffertype const Type, std::string Path, bool const Loadtraction ) { - LoadTraction = tr; + LoadTraction = Loadtraction; // build comments map mComments.insert(commentmap::value_type("/*", "*/")); mComments.insert(commentmap::value_type("//", "\n")); @@ -236,3 +236,8 @@ int cParser::getProgress() const { return static_cast( mStream->rdbuf()->pubseekoff(0, std::ios_base::cur) * 100 / mSize ); } + +void cParser::addCommentStyle( std::string const &Commentstart, std::string const &Commentend ) { + + mComments.insert( commentmap::value_type(Commentstart, Commentend) ); +} diff --git a/parser.h b/parser.h index 80d6536f..5b5d3256 100644 --- a/parser.h +++ b/parser.h @@ -28,8 +28,7 @@ class cParser //: public std::stringstream buffer_TEXT }; // constructors: - cParser(std::string Stream, buffertype Type = buffer_TEXT, std::string Path = "", - bool tr = true); + cParser(std::string const &Stream, buffertype const Type = buffer_TEXT, std::string Path = "", bool const Loadtraction = true ); // destructor: virtual ~cParser(); // methods: @@ -79,9 +78,10 @@ class cParser //: public std::stringstream return !mStream->fail(); }; bool getTokens(int Count = 1, bool ToLower = true, const char *Break = "\n\t ;"); - int getProgress() const; // percentage of file processed. - // load traction? - bool LoadTraction; + // returns percentage of file processed so far + int getProgress() const; + // add custom definition of text which should be ignored when retrieving tokens + void addCommentStyle( std::string const &Commentstart, std::string const &Commentend ); private: // methods: @@ -92,6 +92,7 @@ class cParser //: public std::stringstream bool findQuotes( std::string &String ); bool trimComments( std::string &String ); // members: + bool LoadTraction; // load traction? std::istream *mStream; // relevant kind of buffer is attached on creation. std::string mPath; // path to open stream, for relative path lookups. std::streamoff mSize; // size of open stream, for progress report. @@ -133,7 +134,9 @@ cParser::operator>>( bool &Right ) { if( true == this->tokens.empty() ) { return *this; } - Right = ( this->tokens.front() == "true" ); + Right = ( ( this->tokens.front() == "true" ) + || ( this->tokens.front() == "yes" ) + || ( this->tokens.front() == "1" ) ); this->tokens.pop_front(); return *this; diff --git a/stdafx.h b/stdafx.h index c822e7d0..22d52bd3 100644 --- a/stdafx.h +++ b/stdafx.h @@ -23,6 +23,7 @@ #include #include #undef NOMINMAX +#include // stl #include #include