From 435dc24d3eeae95d2c268f3640906cc67278de13 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sat, 9 Sep 2017 00:55:16 +0200 Subject: [PATCH] build 170908. minor refactoring and diagnostics enhancements, virtual coupling fix, support for pantograph compressor submodels --- Driver.cpp | 10 ++-- DynObj.cpp | 136 ++++++++++++++++++++++++--------------------- Event.cpp | 120 ++++++++++++++++++++------------------- Ground.cpp | 16 +++--- McZapkie/MOVER.h | 1 - McZapkie/Mover.cpp | 88 ++++++++++++++--------------- Timer.cpp | 17 +++--- Track.cpp | 2 +- Track.h | 2 +- Train.cpp | 70 +++++++++++++++-------- Train.h | 2 + TrkFoll.cpp | 8 +-- version.h | 2 +- 13 files changed, 257 insertions(+), 217 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 3c9b9780..a0e2a58f 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -46,12 +46,12 @@ ProjectEventOnTrack( TEvent const *Event, TTrack const *Track, double const Dire ( 1.0 - nearestpoint ) * segment->GetLength() ); // measure from point2 }; -double GetDistanceToEvent(TTrack* track, TEvent* event, double scan_dir, double start_dist, int iter = 0, bool back = false) +double GetDistanceToEvent(TTrack const *track, TEvent const *event, double scan_dir, double start_dist, int iter = 0, bool back = false) { if( track == nullptr ) { return start_dist; } auto const segment = track->CurrentSegment(); - vector3 const pos_event = event->PositionGet(); + auto const pos_event = event->PositionGet(); double len1, len2; double sd = scan_dir; double seg_len = scan_dir > 0 ? 0.0 : 1.0; @@ -63,7 +63,7 @@ double GetDistanceToEvent(TTrack* track, TEvent* event, double scan_dir, double len1 = len2; seg_len += scan_dir > 0 ? dzielnik : -dzielnik; len2 = (pos_event - segment->FastGetPoint(seg_len)).LengthSquared(); - krok++; + ++krok; } while ((len1 > len2) && (seg_len >= dzielnik && (seg_len <= (1 - dzielnik)))); //trzeba sprawdzić czy seg_len nie osiągnął skrajnych wartości, bo wtedy // trzeba sprawdzić tor obok @@ -71,7 +71,7 @@ double GetDistanceToEvent(TTrack* track, TEvent* event, double scan_dir, double sd = -sd; // jeśli tylko jeden krok tzn, że event przy poprzednim sprawdzaym torze if (((seg_len <= dzielnik) || (seg_len > (1 - dzielnik))) && (iter < 3)) { // przejście na inny tor - track = track->Neightbour(int(sd), sd); + track = track->Connected(int(sd), sd); start_dist += (1 == krok) ? 0 : back ? -segment->GetLength() : segment->GetLength(); return GetDistanceToEvent(track, event, sd, start_dist, ++iter, 1 == krok ? true : false); } @@ -616,7 +616,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) fCurrentDistance += fTrackLength; // doliczenie kolejnego odcinka do przeskanowanej długości tLast = pTrack; // odhaczenie, że sprawdzony fLastVel = pTrack->VelocityGet(); // prędkość na poprzednio sprawdzonym odcinku - pTrack = pTrack->Neightbour( + pTrack = pTrack->Connected( ( pTrack->eType == tt_Cross ? (sSpeedTable[iLast].iFlags >> 28) : static_cast(fLastDir) ), diff --git a/DynObj.cpp b/DynObj.cpp index f3c24d7f..68c8adb0 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -1262,71 +1262,65 @@ int TDynamicObject::Dettach(int dir) .CouplingFlag; // sprzęg po rozłączaniu (czego się nie da odpiąć } -void TDynamicObject::CouplersDettach(double MinDist, int MyScanDir) -{ // funkcja rozłączajaca podłączone sprzęgi, - // jeśli odległość przekracza (MinDist) +void TDynamicObject::CouplersDettach(double MinDist, int MyScanDir) { + // funkcja rozłączajaca podłączone sprzęgi, jeśli odległość przekracza (MinDist) // MinDist - dystans minimalny, dla ktorego mozna rozłączać - if (MyScanDir > 0) - { - if (PrevConnected) // pojazd od strony sprzęgu 0 - { - if (MoverParameters->Couplers[0].CoupleDist > MinDist) { - // sprzęgi wirtualne zawsze przekraczają - - if ((PrevConnectedNo ? PrevConnected->NextConnected : - PrevConnected->PrevConnected) == this) - { // Ra: nie rozłączamy znalezionego, jeżeli nie do nas - // podłączony (może jechać w - // innym kierunku) - PrevConnected->MoverParameters->Couplers[PrevConnectedNo].Connected = NULL; - if (PrevConnectedNo == 0) - { - PrevConnected->PrevConnectedNo = 2; // sprzęg 0 nie podłączony - PrevConnected->PrevConnected = NULL; - } - else if (PrevConnectedNo == 1) - { - PrevConnected->NextConnectedNo = 2; // sprzęg 1 nie podłączony - PrevConnected->NextConnected = NULL; - } + if (MyScanDir > 0) { + // pojazd od strony sprzęgu 0 + if( ( PrevConnected != nullptr ) + && ( MoverParameters->Couplers[ TMoverParameters::side::front ].CoupleDist > MinDist ) ) { + // sprzęgi wirtualne zawsze przekraczają + if( ( PrevConnectedNo == TMoverParameters::side::front ? + PrevConnected->PrevConnected : + PrevConnected->NextConnected ) + == this ) { + // Ra: nie rozłączamy znalezionego, jeżeli nie do nas podłączony + // (może jechać w innym kierunku) + PrevConnected->MoverParameters->Couplers[PrevConnectedNo].Connected = nullptr; + if( PrevConnectedNo == TMoverParameters::side::front ) { + // sprzęg 0 nie podłączony + PrevConnected->PrevConnectedNo = 2; + PrevConnected->PrevConnected = nullptr; + } + else if( PrevConnectedNo == TMoverParameters::side::rear ) { + // sprzęg 1 nie podłączony + PrevConnected->NextConnectedNo = 2; + PrevConnected->NextConnected = nullptr; } - - // za to zawsze odłączamy siebie - PrevConnected = NULL; - PrevConnectedNo = 2; // sprzęg 0 nie podłączony - MoverParameters->Couplers[0].Connected = nullptr; } + // za to zawsze odłączamy siebie + PrevConnected = nullptr; + PrevConnectedNo = 2; // sprzęg 0 nie podłączony + MoverParameters->Couplers[ TMoverParameters::side::front ].Connected = nullptr; } } - else - { - if (NextConnected) // pojazd od strony sprzęgu 1 - { - if (MoverParameters->Couplers[1].CoupleDist > MinDist) { - // sprzęgi wirtualne zawsze przekraczają - - if ((NextConnectedNo ? NextConnected->NextConnected : - NextConnected->PrevConnected) == this) - { // Ra: nie rozłączamy znalezionego, jeżeli nie do nas - // podłączony (może jechać w - // innym kierunku) - NextConnected->MoverParameters->Couplers[NextConnectedNo].Connected = NULL; - if (NextConnectedNo == 0) - { - NextConnected->PrevConnectedNo = 2; // sprzęg 0 nie podłączony - NextConnected->PrevConnected = NULL; - } - else if (NextConnectedNo == 1) - { - NextConnected->NextConnectedNo = 2; // sprzęg 1 nie podłączony - NextConnected->NextConnected = NULL; - } + else { + // pojazd od strony sprzęgu 1 + if( ( NextConnected != nullptr ) + && ( MoverParameters->Couplers[ TMoverParameters::side::rear ].CoupleDist > MinDist ) ) { + // sprzęgi wirtualne zawsze przekraczają + if( ( NextConnectedNo == TMoverParameters::side::front ? + NextConnected->PrevConnected : + NextConnected->NextConnected ) + == this) { + // Ra: nie rozłączamy znalezionego, jeżeli nie do nas podłączony + // (może jechać w innym kierunku) + NextConnected->MoverParameters->Couplers[ NextConnectedNo ].Connected = nullptr; + if( NextConnectedNo == TMoverParameters::side::front ) { + // sprzęg 0 nie podłączony + NextConnected->PrevConnectedNo = 2; + NextConnected->PrevConnected = nullptr; + } + else if( NextConnectedNo == TMoverParameters::side::rear ) { + // sprzęg 1 nie podłączony + NextConnected->NextConnectedNo = 2; + NextConnected->NextConnected = nullptr; } - - NextConnected = NULL; - NextConnectedNo = 2; // sprzęg 1 nie podłączony - MoverParameters->Couplers[1].Connected = nullptr; } + // za to zawsze odłączamy siebie + NextConnected = nullptr; + NextConnectedNo = 2; // sprzęg 1 nie podłączony + MoverParameters->Couplers[1].Connected = nullptr; } } } @@ -1428,6 +1422,18 @@ void TDynamicObject::ABuScanObjects( int Direction, double Distance ) if( foundobject->MoverParameters->Couplers[ foundcoupler ].CouplingFlag == coupling::faux ) { // Ra: wpinamy się wirtualnym tylko jeśli znaleziony ma wirtualny sprzęg + if( ( foundcoupler == TMoverParameters::side::front ? + foundobject->PrevConnected : + foundobject->NextConnected ) + != this ) { + // but first break existing connection of the target, + // otherwise we risk leaving the target's connected vehicle with active one-side connection + foundobject->CouplersDettach( + 1.0, + ( foundcoupler == TMoverParameters::side::front ? + 1 : + -1 ) ); + } foundobject->MoverParameters->Attach( foundcoupler, mycoupler, this->MoverParameters, coupling::faux ); if( foundcoupler == TMoverParameters::side::front ) { @@ -2577,15 +2583,19 @@ bool TDynamicObject::Update(double dt, double dt1) tp.CategoryFlag = MyTrack->iCategoryFlag & 15; tp.DamageFlag = MyTrack->iDamageFlag; tp.QualityFlag = MyTrack->iQualityFlag; - if ((MoverParameters->Couplers[0].CouplingFlag > 0) && - (MoverParameters->Couplers[1].CouplingFlag > 0)) - { + + // couplers + if( ( MoverParameters->Couplers[ 0 ].CouplingFlag != coupling::faux ) + && ( MoverParameters->Couplers[ 1 ].CouplingFlag != coupling::faux ) ) { + MoverParameters->InsideConsist = true; } - else - { + else { + MoverParameters->InsideConsist = false; } + // + // napiecie sieci trakcyjnej // Ra 15-01: przeliczenie poboru prądu powinno być robione wcześniej, żeby na // tym etapie były diff --git a/Event.cpp b/Event.cpp index 42ee01c3..5461c74d 100644 --- a/Event.cpp +++ b/Event.cpp @@ -140,10 +140,7 @@ void TEvent::Conditions(cParser *parser, std::string s) void TEvent::Load(cParser *parser, vector3 *org) { - int i; - int ti; std::string token; - //string str; bEnabled = true; // zmieniane na false dla eventów używanych do skanowania sygnałów @@ -247,47 +244,47 @@ void TEvent::Load(cParser *parser, vector3 *org) *parser >> token; Conditions(parser, token); // sprawdzanie warunków break; - case tp_CopyValues: - Params[9].asText = NULL; + case tp_CopyValues: { + Params[9].asText = nullptr; iFlags = update_memstring | update_memval1 | update_memval2; // normalanie trzy - i = 0; + int paramidx { 0 }; parser->getTokens(); *parser >> token; // nazwa drugiej komórki (źródłowej) - while (token.compare("endevent") != 0) - { - switch (++i) + while (token.compare("endevent") != 0) { + + switch (++paramidx) { // znaczenie kolejnych parametrów case 1: // nazwa drugiej komórki (źródłowej) Params[9].asText = new char[token.size() + 1]; // usuwane i zamieniane na wskaźnik strcpy(Params[9].asText, token.c_str()); break; case 2: // maska wartości - iFlags = stol_def(token, - (update_memstring | update_memval1 | update_memval2)); + iFlags = stol_def(token, (update_memstring | update_memval1 | update_memval2)); break; } parser->getTokens(); *parser >> token; } break; - case tp_WhoIs: + } + case tp_WhoIs: { iFlags = update_memstring | update_memval1 | update_memval2; // normalanie trzy - i = 0; + int paramidx { 0 }; parser->getTokens(); *parser >> token; // nazwa drugiej komórki (źródłowej) - while (token.compare("endevent") != 0) - { - switch (++i) - { // znaczenie kolejnych parametrów - case 1: // maska wartości - iFlags = stol_def(token, - (update_memstring | update_memval1 | update_memval2)); - break; + while( token.compare( "endevent" ) != 0 ) { + switch( ++paramidx ) { // znaczenie kolejnych parametrów + case 1: // maska wartości + iFlags = stol_def( token, ( update_memstring | update_memval1 | update_memval2 ) ); + break; + default: + break; } parser->getTokens(); *parser >> token; } break; + } case tp_GetValues: case tp_LogValues: parser->getTokens(); //"endevent" @@ -384,25 +381,27 @@ void TEvent::Load(cParser *parser, vector3 *org) parser->getTokens(); *parser >> token; break; - case tp_Lights: - i = 0; - do - { + case tp_Lights: { + int paramidx { 0 }; + do { parser->getTokens(); *parser >> token; - if (token.compare("endevent") != 0) - { - // str = AnsiString(token.c_str()); - if (i < 8) - Params[i].asdouble = atof(token.c_str()); // teraz może mieć ułamek - i++; + if( token.compare( "endevent" ) != 0 ) { + + if( paramidx < 8 ) { + Params[ paramidx ].asdouble = atof( token.c_str() ); // teraz może mieć ułamek + ++paramidx; + } + else { + ErrorLog( "Bad event: lights event \"" + asName + "\" with more than 8 parameters" ); + } } - } while (token.compare("endevent") != 0); + } while( token.compare( "endevent" ) != 0 ); break; + } case tp_Visible: // zmiana wyświetlania obiektu parser->getTokens(); *parser >> token; - // str = AnsiString(token.c_str()); Params[0].asInt = atoi(token.c_str()); parser->getTokens(); *parser >> token; @@ -410,7 +409,6 @@ void TEvent::Load(cParser *parser, vector3 *org) case tp_Velocity: parser->getTokens(); *parser >> token; - // str = AnsiString(token.c_str()); Params[0].asdouble = atof(token.c_str()) * 0.28; parser->getTokens(); *parser >> token; @@ -544,38 +542,46 @@ void TEvent::Load(cParser *parser, vector3 *org) parser->getTokens(); *parser >> token; break; - case tp_Multiple: - i = 0; - ti = 0; // flaga dla else + case tp_Multiple: { + int paramidx { 0 }; + bool ti { false }; // flaga dla else parser->getTokens(); *parser >> token; - // str = AnsiString(token.c_str()); - while (token != "endevent" && token != "condition" && - token != "randomdelay") - { - if ((token.substr(0, 5) != "none_") ? (i < 8) : false) - { // eventy rozpoczynające się od "none_" są ignorowane - if (token != "else") - { - Params[i].asText = new char[token.size() + 1]; - strcpy(Params[i].asText, token.c_str()); - if (ti) - iFlags |= conditional_else << i; // oflagowanie dla eventów "else" - i++; + + while( ( token != "endevent" ) + && ( token != "condition" ) + && ( token != "randomdelay" ) ) { + + if( token != "else" ) { + if( token.substr( 0, 5 ) != "none_" ) { + // eventy rozpoczynające się od "none_" są ignorowane + if( paramidx < 8 ) { + Params[ paramidx ].asText = new char[ token.size() + 1 ]; + strcpy( Params[ paramidx ].asText, token.c_str() ); + if( ti ) { + // oflagowanie dla eventów "else" + iFlags |= conditional_else << paramidx; + } + ++paramidx; + } + else { + ErrorLog( "Bad event: multi-event \"" + asName + "\" with more than 8 events; discarding link to event \"" + token + "\"" ); + } + } + else { + WriteLog( "Multi-event \"" + asName + "\" ignored link to event \"" + token + "\"" ); } - else - ti = !ti; // zmiana flagi dla słowa "else" } - else if (i >= 8) - ErrorLog("Bad event: \"" + token + "\" ignored in multiple \"" + asName + "\"!"); - else - WriteLog("Event \"" + token + "\" ignored in multiple \"" + asName + "\"!"); + else { + // zmiana flagi dla słowa "else" + ti = !ti; + } parser->getTokens(); *parser >> token; - // str = AnsiString(token.c_str()); } Conditions(parser, token); // sprawdzanie warunków break; + } case tp_Voltage: // zmiana napięcia w zasilaczu (TractionPowerSource) case tp_Friction: // zmiana przyczepnosci na scenerii parser->getTokens(); diff --git a/Ground.cpp b/Ground.cpp index 8c2a349d..482ced09 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -2175,11 +2175,11 @@ bool TGround::Init(std::string File) { // możliwość przedefiniowania parametrów w scenerii Global::ConfigParse(parser); // parsowanie dodatkowych ustawień } - else if (str != "") - { // pomijanie od nierozpoznanej komendy do jej zakończenia - if ((token.length() > 2) && (atof(token.c_str()) == 0.0)) - { // jeśli nie liczba, to spróbować pominąć komendę - WriteLog("Unrecognized command: " + str); + else if (str != "") { + // pomijanie od nierozpoznanej komendy do jej zakończenia + if ((token.length() > 2) && (atof(token.c_str()) == 0.0)) { + // jeśli nie liczba, to spróbować pominąć komendę + WriteLog( "Unrecognized command: \"" + str + "\" encountered in file \"" + parser.Name() + "\" (line " + std::to_string( parser.Line() - 1 ) + ")" ); str = "end" + str; do { @@ -2188,8 +2188,10 @@ bool TGround::Init(std::string File) parser >> token; } while ((token != "") && (token.compare(str.c_str()) != 0)); } - else // jak liczba to na pewno błąd - Error("Unrecognized command: " + str); + else { + // jak liczba to na pewno błąd + ErrorLog( "Unrecognized command: \"" + str + "\" encountered in file \"" + parser.Name() + "\" (line " + std::to_string( parser.Line() - 1 ) + ")" ); + } } token = ""; diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index bcb743c9..642c7bfb 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -813,7 +813,6 @@ public: voltage }; #endif - int ScanCounter = 0; /*pomocnicze do skanowania sprzegow*/ bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/ int SoundFlag = 0; /*!o patrz stale sound_ */ double DistCounter = 0.0; /*! licznik kilometrow */ diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 088e0074..8f00004a 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -473,7 +473,7 @@ bool TMoverParameters::Attach(int ConnectNo, int ConnectToNr, TMoverParameters * coupler.Connected = ConnectTo; // tak podpiąć (do siebie) zawsze można, najwyżej będzie wirtualny CouplerDist( ConnectNo ); // przeliczenie odległości pomiędzy sprzęgami - if (CouplingType == ctrain_virtual) + if (CouplingType == coupling::faux) return false; // wirtualny więcej nic nie robi auto &othercoupler = ConnectTo->Couplers[ coupler.ConnectedNr ]; @@ -555,21 +555,29 @@ bool TMoverParameters::Dettach(int ConnectNo) return false; // jeszcze nie rozłączony }; -void TMoverParameters::SetCoupleDist() -{ // przeliczenie odległości sprzęgów - if (Couplers[0].Connected) - { - CouplerDist(0); - if (CategoryFlag & 2) - { // Ra: dla samochodów zderzanie kul to za mało +// przeliczenie odległości sprzęgów +void TMoverParameters::SetCoupleDist() { +/* + double const MaxDist = 100.0; // 2x average max proximity distance. TODO: rearrange ito something more elegant +*/ + for( int coupleridx = 0; coupleridx <= 1; ++coupleridx ) { + + if( Couplers[ coupleridx ].Connected == nullptr ) { continue; } + + CouplerDist( coupleridx ); + if( CategoryFlag & 2 ) { + // Ra: dla samochodów zderzanie kul to za mało + // NOTE: whatever calculation was supposed to be here, ain't } - } - if (Couplers[1].Connected) - { - CouplerDist(1); - if (CategoryFlag & 2) - { // Ra: dla samochodów zderzanie kul to za mało +/* + if( ( Couplers[ coupleridx ].CouplingFlag == coupling::faux ) + && ( Couplers[ coupleridx ].CoupleDist > MaxDist ) ) { + // zerwij kontrolnie wirtualny sprzeg + // Connected.Couplers[CNext].Connected:=nil; //Ra: ten podłączony niekoniecznie jest wirtualny + Couplers[ coupleridx ].Connected = nullptr; + Couplers[ coupleridx ].ConnectedNr = 2; } +*/ } }; @@ -3725,14 +3733,12 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer) else { Voltage = 0; } - //if (Mains && /*(abs(CabNo) < 2) &&*/ ( - // EngineType == ElectricInductionMotor)) // potem ulepszyc! pantogtrafy! - // Voltage = RunningTraction.TractionVoltage; if (Power > 0) FTrain = TractionForce(dt); else FTrain = 0; + Fb = BrakeForce(RunningTrack); Fwheels = FTrain - Fb * Sign(V); if( ( Vel > 0.001 ) // crude trap, to prevent braked stationary vehicles from passing fb > mass * adhesive test @@ -3966,7 +3972,7 @@ double TMoverParameters::Adhesive(double staticfriction) // WriteLog(FloatToStr(adhesive)); // tutaj jest na poziomie 0.2 - 0.3 return adhesion; */ - /* //wersja druga + //wersja druga if( true == SlippingWheels ) { if( true == SandDose ) { adhesion = 0.48; } @@ -3977,12 +3983,15 @@ double TMoverParameters::Adhesive(double staticfriction) 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; */ +// adhesion *= ( 0.9 + 0.2 * Random() ); +/* //wersja3 by youBy - uwzględnia naturalne mikropoślizgi i wpływ piasecznicy, usuwa losowość z pojazdu double Vwheels = nrot * M_PI * WheelDiameter; // predkosc liniowa koła wynikająca z obrotowej double deltaV = V - Vwheels; //poślizg - różnica prędkości w punkcie styku koła i szyny deltaV = std::max(0.0, std::abs(deltaV) - 0.25); //mikropoślizgi do ok. 0,25 m/s nie zrywają przyczepności - adhesion = staticfriction * (28 + Vwheels) / (14 + Vwheels) * ((SandDose? sandfactor : 1) - (1 - adh_factor)*(deltaV / (deltaV + slipfactor))); + Vwheels = std::abs( Vwheels ); + adhesion = staticfriction * (28 + Vwheels) / (14 + Vwheels) * ((SandDose? sandfactor : 1) - (1 - adh_factor)*(deltaV / (deltaV + slipfactor))); +*/ return adhesion; } @@ -4052,24 +4061,11 @@ double TMoverParameters::CouplerForce(int CouplerN, double dt) // blablabla // ABu: proby znalezienia problemu ze zle odbijajacymi sie skladami //if (Couplers[CouplerN].CouplingFlag=ctrain_virtual) and (newdist>0) then - if ((Couplers[CouplerN].CouplingFlag == ctrain_virtual) && (Couplers[CouplerN].CoupleDist > 0)) - { - CF = 0; // kontrola zderzania sie - OK - ScanCounter++; - if ((newdist > MaxDist) || ((ScanCounter > MaxCount) && (newdist > MinDist))) - //if (tempdist>MaxDist) or ((ScanCounter>MaxCount)and(tempdist>MinDist)) then - { // zerwij kontrolnie wirtualny sprzeg - // Connected.Couplers[CNext].Connected:=nil; //Ra: ten podłączony niekoniecznie jest - // wirtualny -// Couplers[CouplerN].Connected = NULL; - ScanCounter = static_cast(Random(500.0)); // Q: TODO: cy dobrze przetlumaczone? - // WriteLog(FloatToStr(ScanCounter)); - } - } - else - { - if (Couplers[CouplerN].CouplingFlag == ctrain_virtual) - { + if( ( Couplers[ CouplerN ].CouplingFlag != coupling::faux ) + || ( Couplers[ CouplerN ].CoupleDist < 0 ) ) { + + if( Couplers[ CouplerN ].CouplingFlag == coupling::faux ) { + BetaAvg = Couplers[CouplerN].beta; Fmax = (Couplers[CouplerN].FmaxC + Couplers[CouplerN].FmaxB) * CouplerTune; } @@ -4145,18 +4141,20 @@ double TMoverParameters::CouplerForce(int CouplerN, double dt) //***if -tempdist>(DmaxB+Connected^.Couplers[CNext].DmaxB)/10 then {zderzenie} { Couplers[CouplerN].CheckCollision = true; - if ((Couplers[CouplerN].CouplerType == Automatic) && - (Couplers[CouplerN].CouplingFlag == - 0)) // sprzeganie wagonow z samoczynnymi sprzegami} + if( ( Couplers[ CouplerN ].CouplerType == Automatic ) + && ( Couplers[ CouplerN ].CouplingFlag == coupling::faux ) ) { + // sprzeganie wagonow z samoczynnymi sprzegami} // CouplingFlag:=ctrain_coupler+ctrain_pneumatic+ctrain_controll+ctrain_passenger+ctrain_scndpneumatic; - Couplers[CouplerN].CouplingFlag = - ctrain_coupler | ctrain_pneumatic | ctrain_controll; // EN57 + // EN57 + Couplers[ CouplerN ].CouplingFlag = coupling::coupler | coupling::brakehose | coupling::mainhose | coupling::control; + } } } } - if (Couplers[CouplerN].CouplingFlag != ctrain_virtual) + if( Couplers[ CouplerN ].CouplingFlag != coupling::faux ) { // uzgadnianie prawa Newtona - Couplers[CouplerN].Connected->Couplers[1 - CouplerN].CForce = -CF; + Couplers[ CouplerN ].Connected->Couplers[ 1 - CouplerN ].CForce = -CF; + } return CF; } diff --git a/Timer.cpp b/Timer.cpp index 1ddd600b..e78b50a7 100644 --- a/Timer.cpp +++ b/Timer.cpp @@ -66,9 +66,9 @@ void ResetTimers() }; LONGLONG fr, count, oldCount; -// LARGE_INTEGER fr,count; -void UpdateTimers(bool pause) -{ + +void UpdateTimers(bool pause) { + QueryPerformanceFrequency((LARGE_INTEGER *)&fr); QueryPerformanceCounter((LARGE_INTEGER *)&count); DeltaRenderTime = double(count - oldCount) / double(fr); @@ -78,18 +78,14 @@ void UpdateTimers(bool pause) fSoundTimer += DeltaTime; if (fSoundTimer > 0.1) fSoundTimer = 0.0; - /* - double CurrentTime= double(count)/double(fr);//GetTickCount(); - DeltaTime= (CurrentTime-OldTime); - OldTime= CurrentTime; - */ + if (DeltaTime > 1.0) DeltaTime = 1.0; } else DeltaTime = 0.0; // wszystko stoi, bo czas nie płynie - oldCount = count; + oldCount = count; // Keep track of the time lapse and frame count #if _WIN32_WINNT >= _WIN32_WINNT_VISTA double fTime = ::GetTickCount64() * 0.001f; // Get current time in seconds @@ -106,6 +102,7 @@ void UpdateTimers(bool pause) } fSimulationTime += DeltaTime; }; -}; + +}; // namespace timer //--------------------------------------------------------------------------- diff --git a/Track.cpp b/Track.cpp index 6814d710..ed464b22 100644 --- a/Track.cpp +++ b/Track.cpp @@ -2340,7 +2340,7 @@ void TTrack::ConnectionsLog() } }; -TTrack * TTrack::Neightbour(int s, double &d) +TTrack * TTrack::Connected(int s, double &d) const { // zwraca wskaźnik na sąsiedni tor, w kierunku określonym znakiem (s), odwraca (d) w razie // niezgodności kierunku torów TTrack *t; // nie zmieniamy kierunku (d), jeśli nie ma toru dalej diff --git a/Track.h b/Track.h index 323bfb69..91ea6138 100644 --- a/Track.h +++ b/Track.h @@ -205,7 +205,7 @@ public: return trNext; }; inline TTrack *CurrentPrev() const { return trPrev; }; - TTrack * Neightbour(int s, double &d); + TTrack *Connected(int s, double &d) const; bool SetConnections(int i); bool Switch(int i, double t = -1.0, double d = -1.0); bool SwitchForced(int i, TDynamicObject *o); diff --git a/Train.cpp b/Train.cpp index c6f54547..5cd946e8 100644 --- a/Train.cpp +++ b/Train.cpp @@ -1430,10 +1430,14 @@ void TTrain::OnCommand_pantographcompressorvalvetoggle( TTrain *Train, command_d if( Train->mvControlled->bPantKurek3 == false ) { // connect pantographs with primary tank Train->mvControlled->bPantKurek3 = true; + // visual feedback: + Train->ggPantCompressorValve.UpdateValue( 0.0 ); } else { // connect pantograps with pantograph compressor Train->mvControlled->bPantKurek3 = false; + // visual feedback: + Train->ggPantCompressorValve.UpdateValue( 1.0 ); } } } @@ -1456,10 +1460,14 @@ void TTrain::OnCommand_pantographcompressoractivate( TTrain *Train, command_data if( Command.action != GLFW_RELEASE ) { // press or hold to activate Train->mvControlled->PantCompFlag = true; + // visual feedback: + Train->ggPantCompressorButton.UpdateValue( 1.0 ); } else { // release to disable Train->mvControlled->PantCompFlag = false; + // visual feedback: + Train->ggPantCompressorButton.UpdateValue( 0.0 ); } } @@ -4627,35 +4635,38 @@ bool TTrain::Update( double const Deltatime ) ggBrakeCtrl.UpdateValue(mvOccupied->fBrakeCtrlPos); ggBrakeCtrl.Update(); } - if (ggLocalBrake.SubModel) - { - if (DynamicObject->Mechanik ? - (DynamicObject->Mechanik->AIControllFlag ? false : (Global::iFeedbackMode == 4 || (Global::bMWDmasterEnable && Global::bMWDBreakEnable))) : - false) // nie blokujemy AI - { // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba - // Firleju: dlatego kasujemy i zastepujemy funkcją w Console - if ((mvOccupied->BrakeLocHandle == FD1)) - { - double b = Console::AnalogCalibrateGet(1); - b *= 10.0; - b = clamp( b, 0.0, LocalBrakePosNo); // przycięcie zmiennej do granic - ggLocalBrake.UpdateValue(b); // przesów bez zaokrąglenia - if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("FD1 break position = " + to_string(b)); - mvOccupied->LocalBrakePos = - int(1.09 * b); // sposób zaokrąglania jest do ustalenia + + if( ggLocalBrake.SubModel ) { + + if( ( DynamicObject->Mechanik != nullptr ) + && ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI + && ( mvOccupied->BrakeLocHandle == FD1 ) + && ( ( Global::iFeedbackMode == 4 ) + || ( Global::bMWDmasterEnable && Global::bMWDBreakEnable ) ) ) { + // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba + // Firleju: dlatego kasujemy i zastepujemy funkcją w Console + auto const b = clamp( + Console::AnalogCalibrateGet( 1 ) * 10.0, + 0.0, + ManualBrakePosNo ); + ggLocalBrake.UpdateValue( b ); // przesów bez zaokrąglenia + mvOccupied->LocalBrakePos = int( 1.09 * b ); // sposób zaokrąglania jest do ustalenia + if( ( true == Global::bMWDdebugEnable ) + && ( ( Global::iMWDDebugMode & 4 ) != 0 ) ) { + WriteLog( "FD1 break position = " + to_string( b ) ); } - else // standardowa prodedura z kranem powiązanym z klawiaturą - ggLocalBrake.UpdateValue(double(mvOccupied->LocalBrakePos)); } - else // standardowa prodedura z kranem powiązanym z klawiaturą - ggLocalBrake.UpdateValue(double(mvOccupied->LocalBrakePos)); + else { + // standardowa prodedura z kranem powiązanym z klawiaturą + ggLocalBrake.UpdateValue( double( mvOccupied->LocalBrakePos ) ); + } ggLocalBrake.Update(); } - if (ggManualBrake.SubModel != NULL) - { + if (ggManualBrake.SubModel != nullptr) { ggManualBrake.UpdateValue(double(mvOccupied->ManualBrakePos)); ggManualBrake.Update(); } + ggAlarmChain.Update(); ggBrakeProfileCtrl.Update(); ggBrakeProfileG.Update(); ggBrakeProfileR.Update(); @@ -5629,6 +5640,8 @@ bool TTrain::Update( double const Deltatime ) ggPantRearButtonOff.Update(); ggPantSelectedDownButton.Update(); ggPantAllDownButton.Update(); + ggPantCompressorButton.Update(); + ggPantCompressorValve.Update(); ggUpperLightButton.Update(); ggLeftLightButton.Update(); @@ -6503,6 +6516,8 @@ void TTrain::clear_cab_controls() ggPantRearButtonOff.Clear(); ggPantSelectedDownButton.Clear(); ggPantAllDownButton.Clear(); + ggPantCompressorButton.Clear(); + ggPantCompressorValve.Clear(); ggZbS.Clear(); ggI1B.Clear(); ggI2B.Clear(); @@ -6649,6 +6664,15 @@ void TTrain::set_cab_controls() { 0.0 : 1.0 ) ); } + // auxiliary compressor + ggPantCompressorValve.PutValue( + mvControlled->bPantKurek3 ? + 0.0 : // default setting is pantographs connected with primary tank + 1.0 ); + ggPantCompressorButton.PutValue( + mvControlled->PantCompFlag ? + 1.0 : + 0.0 ); // converter if( mvOccupied->ConvSwitchType != "impulse" ) { ggConverterButton.PutValue( @@ -7067,6 +7091,8 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con { "pantalloff_sw:", ggPantAllDownButton }, { "pantselected_sw:", ggPantSelectedButton }, { "pantselectedoff_sw:", ggPantSelectedDownButton }, + { "pantcompressor_sw:", ggPantCompressorButton }, + { "pantcompressorvalve_sw:", ggPantCompressorValve }, { "trainheating_sw:", ggTrainHeatingButton }, { "signalling_sw:", ggSignallingButton }, { "door_signalling_sw:", ggDoorSignallingButton }, diff --git a/Train.h b/Train.h index 90a5ac6d..166f2cc1 100644 --- a/Train.h +++ b/Train.h @@ -299,6 +299,8 @@ public: // reszta może by?publiczna TGauge ggPantAllDownButton; TGauge ggPantSelectedButton; TGauge ggPantSelectedDownButton; + TGauge ggPantCompressorButton; + TGauge ggPantCompressorValve; // Winger 020304 - wlacznik ogrzewania TGauge ggTrainHeatingButton; TGauge ggSignallingButton; diff --git a/TrkFoll.cpp b/TrkFoll.cpp index c48ecac6..ceddcb1c 100644 --- a/TrkFoll.cpp +++ b/TrkFoll.cpp @@ -206,10 +206,10 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary) dir = fDirection; if (pCurrentTrack->eType == tt_Cross) { - if (!SetCurrentTrack(pCurrentTrack->Neightbour(iSegment, fDirection), 0)) + if (!SetCurrentTrack(pCurrentTrack->Connected(iSegment, fDirection), 0)) return false; // wyjście z błędem } - else if (!SetCurrentTrack(pCurrentTrack->Neightbour(-1, fDirection), + else if (!SetCurrentTrack(pCurrentTrack->Connected(-1, fDirection), 0)) // ustawia fDirection return false; // wyjście z błędem if (dir == fDirection) //(pCurrentTrack->iPrevDirection) @@ -243,10 +243,10 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary) dir = fDirection; if (pCurrentTrack->eType == tt_Cross) { - if (!SetCurrentTrack(pCurrentTrack->Neightbour(iSegment, fDirection), 1)) + if (!SetCurrentTrack(pCurrentTrack->Connected(iSegment, fDirection), 1)) return false; // wyjście z błędem } - else if (!SetCurrentTrack(pCurrentTrack->Neightbour(1, fDirection), + else if (!SetCurrentTrack(pCurrentTrack->Connected(1, fDirection), 1)) // ustawia fDirection return false; // wyjście z błędem if (dir != fDirection) //(pCurrentTrack->iNextDirection) diff --git a/version.h b/version.h index 998e22bf..49b29887 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 17 -#define VERSION_MINOR 905 +#define VERSION_MINOR 908 #define VERSION_REVISION 0