From f06f997946f4b719445f07574021c8cf5fd532f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Sun, 20 Aug 2017 20:22:04 +0200 Subject: [PATCH 1/5] AI: Better acceleration with ElectricSeriesMotor - motor current is set acording to ahdesion and fuse limit --- Driver.cpp | 139 +++++++++++++++++++++++++++++++++++------------------ Driver.h | 1 + 2 files changed, 94 insertions(+), 46 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 7442464d..42d3c222 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1720,7 +1720,41 @@ void TController::AutoRewident() fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 1 * fBrake_a1[BrakeAccTableSize]; fBrakeReaction = 1.00 + fLength*0.005; } -}; +} + +double TController::ESMVelocity(bool Main) +{ + double fCurrentCoeff = 0.9; + double fFrictionCoeff = 0.85; + double ESMVel = 9999; + int MCPN = mvControlling->MainCtrlActualPos; + int SCPN = mvControlling->ScndCtrlActualPos; + if (Main) + MCPN += 1; + else + SCPN += 1; + if ((mvControlling->RList[MCPN].ScndAct < 255)&&(mvControlling->ScndCtrlActualPos==0)) + SCPN = mvControlling->RList[MCPN].ScndAct; + double FrictionMax = mvControlling->Mass*9.81*mvControlling->Adhesive(mvControlling->RunningTrack.friction)*fFrictionCoeff; + double IF = mvControlling->Imax; + double MS = 0; + double Fmax = 0; + for (int i = 0; i < 5; i++) + { + MS = mvControlling->MomentumF(IF, IF, SCPN); + Fmax = MS * mvControlling->RList[MCPN].Bn*mvControlling->RList[MCPN].Mn * 2 / mvControlling->WheelDiameter * mvControlling->Transmision.Ratio; + IF = 0.5*IF*(1 + FrictionMax/Fmax); + } + IF = std::min(IF, mvControlling->Imax*fCurrentCoeff); + double R = mvControlling->RList[MCPN].R + mvControlling->CircuitRes + mvControlling->RList[MCPN].Mn*mvControlling->WindingRes; + double pole = mvControlling->MotorParam[SCPN].fi * + std::max(abs(IF) / (abs(IF) + mvControlling->MotorParam[SCPN].Isat) - mvControlling->MotorParam[SCPN].fi0, 0.0); + double Us = abs(mvControlling->Voltage) - IF*R; + double ns = std::max(0.0, Us / (pole*mvControlling->RList[MCPN].Mn)); + ESMVel = ns * mvControlling->WheelDiameter*M_PI*3.6/mvControlling->Transmision.Ratio; + return ESMVel; +} +; int TController::CheckDirection() { @@ -2499,51 +2533,64 @@ bool TController::IncSpeed() (mvControlling->StLinFlag)) // youBy polecił dodać 2012-09-08 v367 // na pozycji 0 przejdzie, a na pozostałych będzie czekać, aż się załączą liniowe // (zgaśnie DelayCtrlFlag) - if (Ready || (iDrivigFlags & movePress)) - if (fabs(mvControlling->Im) < - (fReady < 0.4 ? mvControlling->Imin : mvControlling->IminLo)) - { // Ra: wywalał nadmiarowy, bo Im może być ujemne; jak nie odhamowany, to nie - // przesadzać z prądem - if ((mvOccupied->Vel <= 30) || - (mvControlling->Imax > mvControlling->ImaxLo) || - (fVoltage + fVoltage < - mvControlling->EnginePowerSource.CollectorParameters.MinV + - mvControlling->EnginePowerSource.CollectorParameters.MaxV)) - { // bocznik na szeregowej przy ciezkich bruttach albo przy wysokim rozruchu - // pod górę albo przy niskim napięciu - if (mvControlling->MainCtrlPos ? - mvControlling->RList[mvControlling->MainCtrlPos].R > 0.0 : - true) // oporowa - { - OK = (mvControlling->DelayCtrlFlag ? - true : - mvControlling->IncMainCtrl(1)); // kręcimy nastawnik jazdy - if ((OK) && - (mvControlling->MainCtrlPos == - 1)) // czekaj na 1 pozycji, zanim się nie włączą liniowe - iDrivigFlags |= moveIncSpeed; - else - iDrivigFlags &= ~moveIncSpeed; // usunięcie flagi czekania - } - else // jeśli bezoporowa (z wyjątekiem 0) - OK = false; // to dać bocznik - } - else - { // przekroczone 30km/h, można wejść na jazdę równoległą - if (mvControlling->ScndCtrlPos) // jeśli ustawiony bocznik - if (mvControlling->MainCtrlPos < - mvControlling->MainCtrlPosNo - 1) // a nie jest ostatnia pozycja - mvControlling->DecScndCtrl(2); // to bocznik na zero po chamsku - // (ktoś miał to poprawić...) - OK = mvControlling->IncMainCtrl(1); - } - if ((mvControlling->MainCtrlPos > 2) && - (mvControlling->Im == 0)) // brak prądu na dalszych pozycjach - Need_TryAgain = true; // nie załączona lokomotywa albo wywalił - // nadmiarowy - else if (!OK) // nie da się wrzucić kolejnej pozycji - OK = mvControlling->IncScndCtrl(1); // to dać bocznik - } + if (Ready || (iDrivigFlags & movePress)) + { + bool scndctrl = ((mvOccupied->Vel <= 30) || + (mvControlling->Imax > mvControlling->ImaxLo) || + (fVoltage + fVoltage < + mvControlling->EnginePowerSource.CollectorParameters.MinV + + mvControlling->EnginePowerSource.CollectorParameters.MaxV) || + (mvControlling->MainCtrlPos == mvControlling->MainCtrlPosNo)); + scndctrl = ((scndctrl) && (mvControlling->MainCtrlPos > 1) && (mvControlling->RList[mvControlling->MainCtrlActualPos].R < 0.01)&& (mvControlling->ScndCtrlPos != mvControlling->ScndCtrlPosNo)); + double Vs = 99999; + if((mvControlling->MainCtrlPos != mvControlling->MainCtrlPosNo)||(mvControlling->ScndCtrlPos!=mvControlling->ScndCtrlPosNo)) + Vs = ESMVelocity(!scndctrl); + + if ((fabs(mvControlling->Im) < + (fReady < 0.4 ? mvControlling->Imin : mvControlling->IminLo))||(mvControlling->Vel>Vs)) + { // Ra: wywalał nadmiarowy, bo Im może być ujemne; jak nie odhamowany, to nie + // przesadzać z prądem + if ((mvOccupied->Vel <= 30) || + (mvControlling->Imax > mvControlling->ImaxLo) || + (fVoltage + fVoltage < + mvControlling->EnginePowerSource.CollectorParameters.MinV + + mvControlling->EnginePowerSource.CollectorParameters.MaxV)) + { // bocznik na szeregowej przy ciezkich bruttach albo przy wysokim rozruchu + // pod górę albo przy niskim napięciu + if (mvControlling->MainCtrlPos ? + mvControlling->RList[mvControlling->MainCtrlPos].R > 0.0 : + true) // oporowa + { + OK = (mvControlling->DelayCtrlFlag ? + true : + mvControlling->IncMainCtrl(1)); // kręcimy nastawnik jazdy + if ((OK) && + (mvControlling->MainCtrlPos == + 1)) // czekaj na 1 pozycji, zanim się nie włączą liniowe + iDrivigFlags |= moveIncSpeed; + else + iDrivigFlags &= ~moveIncSpeed; // usunięcie flagi czekania + } + else // jeśli bezoporowa (z wyjątekiem 0) + OK = false; // to dać bocznik + } + else + { // przekroczone 30km/h, można wejść na jazdę równoległą + if (mvControlling->ScndCtrlPos) // jeśli ustawiony bocznik + if (mvControlling->MainCtrlPos < + mvControlling->MainCtrlPosNo - 1) // a nie jest ostatnia pozycja + mvControlling->DecScndCtrl(2); // to bocznik na zero po chamsku + // (ktoś miał to poprawić...) + OK = mvControlling->IncMainCtrl(1); + } + if ((mvControlling->MainCtrlPos > 2) && + (mvControlling->Im == 0)) // brak prądu na dalszych pozycjach + Need_TryAgain = true; // nie załączona lokomotywa albo wywalił + // nadmiarowy + else if (!OK) // nie da się wrzucić kolejnej pozycji + OK = mvControlling->IncScndCtrl(1); // to dać bocznik + } + } mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania break; case Dumb: diff --git a/Driver.h b/Driver.h index c21eb050..dc89a672 100644 --- a/Driver.h +++ b/Driver.h @@ -314,6 +314,7 @@ class TController void Activation(); // umieszczenie obsady w odpowiednim członie void ControllingSet(); // znajduje człon do sterowania void AutoRewident(); // ustawia hamulce w składzie + double ESMVelocity(bool Main); public: Mtable::TTrainParameters *Timetable() { From a0f705292af03e2fca5e980a63feb65512116770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Tue, 5 Sep 2017 20:14:58 +0200 Subject: [PATCH 2/5] New formula for adhesion, fixed some bugs in calculation of wheels' rotation --- Driver.cpp | 2 +- McZapkie/Mover.cpp | 52 ++++++++++++++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 42d3c222..12af005a 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -4821,7 +4821,7 @@ bool TController::UpdateSituation(double dt) else mvControlling->AntiSlippingButton(); ++iDriverFailCount; - mvControlling->SlippingWheels = false; // flaga już wykorzystana + //mvControlling->SlippingWheels = false; // flaga już wykorzystana } if (iDriverFailCount > maxdriverfails) { diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 1a371675..ba9b03f1 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -3648,6 +3648,7 @@ double TMoverParameters::ComputeMass(void) void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer) { int b; + double Fwheels = 0.0; if (PhysicActivation) { @@ -3707,19 +3708,35 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer) 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 - && ( std::max( std::abs( FTrain ), Fb ) > TotalMassxg * Adhesive( RunningTrack.friction ) ) ) // poslizg + && ( std::abs(Fwheels) > TotalMassxg * Adhesive( RunningTrack.friction ) ) ) // poslizg { SlippingWheels = true; } if( true == SlippingWheels ) { // TrainForce:=TrainForce-Fb; - nrot = ComputeRotatingWheel((FTrain - Fb * Sign(V) - FStand) / NAxles - + double temp_nrot = ComputeRotatingWheel(Fwheels - Sign(nrot * M_PI * WheelDiameter - V) * - Adhesive(RunningTrack.friction) * TotalMass, + Adhesive(RunningTrack.friction) * TotalMassxg, dt, nrot); - FTrain = Sign(FTrain) * TotalMassxg * Adhesive(RunningTrack.friction); - Fb = std::min(Fb, TotalMassxg * Adhesive(RunningTrack.friction)); + Fwheels = Sign(nrot * M_PI * WheelDiameter - V) * TotalMassxg * Adhesive(RunningTrack.friction); + if (Fwheels*Sign(V)>0) + { + FTrain = Fwheels - Fb; + } + else + { + Fb = FTrain - Fwheels; + } + if (Sign(nrot * M_PI * WheelDiameter - V)*Sign(temp_nrot * M_PI * WheelDiameter - V) < 0) + { + SlippingWheels = false; + temp_nrot = V / M_PI / WheelDiameter; + } + + + nrot = temp_nrot; } // else SlippingWheels:=false; // FStand:=0; @@ -3728,7 +3745,7 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer) (Couplers[b].CouplerType<>Articulated)*/ { // doliczenie sił z innych pojazdów Couplers[b].CForce = CouplerForce(b, dt); - FTrain += Couplers[b].CForce; + FTrain += Couplers[b].CForce; } else Couplers[b].CForce = 0; @@ -3862,16 +3879,6 @@ double TMoverParameters::BrakeForce(const TTrackParam &Track) } else UnitBrakeForce = K * 1000.0; - if (((double)NBpA * UnitBrakeForce > TotalMassxg * Adhesive(RunningTrack.friction) / NAxles) && - (abs(V) > 0.001)) - // poslizg - { - // Fb = Adhesive(Track.friction) * Mass * g; - SlippingWheels = true; - } - //{ else - // begin - //{ SlippingWheels:=false;} // if (LocalBrake=ManualBrake)or(MBrake=true)) and (BrakePress<0.3) then // 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 @@ -3907,7 +3914,10 @@ double TMoverParameters::FrictionForce(double R, int TDamage) // ************************************************************************************************* double TMoverParameters::Adhesive(double staticfriction) { - double adhesion; + double adhesion = 0.0; + const double adh_factor = 0.25; //współczynnik określający, jak bardzo spada tarcie przy poślizgu + const double slipfactor = 0.33; //współczynnik określający, jak szybko spada tarcie przy poślizgu + const double sandfactor = 1.25; //współczynnik określający, jak mocno pomaga piasek /* // ABu: male przerobki, tylko czy to da jakikolwiek skutek w FPS? // w kazdym razie zaciemni kod na pewno :) @@ -3930,6 +3940,7 @@ double TMoverParameters::Adhesive(double staticfriction) // WriteLog(FloatToStr(adhesive)); // tutaj jest na poziomie 0.2 - 0.3 return adhesion; */ + /* //wersja druga if( true == SlippingWheels ) { if( true == SandDose ) { adhesion = 0.48; } @@ -3940,7 +3951,12 @@ 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 *= ( 11.0 - 2 * Random() ) / 10.0; */ + //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))); return adhesion; } From f3a55a1443d2d506306a93e037c62c384912be98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Fri, 8 Sep 2017 22:00:05 +0200 Subject: [PATCH 3/5] Fixed bug with negative adhesion --- McZapkie/Mover.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index ba9b03f1..b8d93467 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -3956,6 +3956,7 @@ double TMoverParameters::Adhesive(double staticfriction) 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 + Vwheels = abs(Vwheels); adhesion = staticfriction * (28 + Vwheels) / (14 + Vwheels) * ((SandDose? sandfactor : 1) - (1 - adh_factor)*(deltaV / (deltaV + slipfactor))); return adhesion; } From c419d9fc8677c75930eba42f435ff366d71a4781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Sat, 16 Sep 2017 22:43:33 +0200 Subject: [PATCH 4/5] Fixed slip calculations, some new parameters for python scripts --- McZapkie/Mover.cpp | 13 +++++++++---- Train.cpp | 47 ++++++++++++++++++++++++++++++++-------------- Train.h | 1 + 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index b8d93467..d7799a8b 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -3720,14 +3720,19 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer) Sign(nrot * M_PI * WheelDiameter - V) * Adhesive(RunningTrack.friction) * TotalMassxg, dt, nrot); - Fwheels = Sign(nrot * M_PI * WheelDiameter - V) * TotalMassxg * Adhesive(RunningTrack.friction); + Fwheels = Sign(temp_nrot * M_PI * WheelDiameter - V) * TotalMassxg * Adhesive(RunningTrack.friction); if (Fwheels*Sign(V)>0) { - FTrain = Fwheels - Fb; + FTrain = Fwheels + Fb*Sign(V); + } + else if (FTrain*Sign(V)>0) + { + Fb = FTrain*Sign(V) - Fwheels*Sign(V); } else { - Fb = FTrain - Fwheels; + Fb = -Fwheels*Sign(V); + FTrain = 0; } if (Sign(nrot * M_PI * WheelDiameter - V)*Sign(temp_nrot * M_PI * WheelDiameter - V) < 0) { @@ -4630,7 +4635,7 @@ double TMoverParameters::TractionForce(double dt) { PosRatio = -Sign(V) * DirAbsolute * eimv[eimv_Fr] / (eimc[eimc_p_Fh] * - Max0R(dtrans / MaxBrakePress[0], AnPos) /*dizel_fill*/); + Max0R(Max0R(dtrans,0.01) / MaxBrakePress[0], AnPos) /*dizel_fill*/); } else PosRatio = 0; diff --git a/Train.cpp b/Train.cpp index 46dbb7b9..e6f4902b 100644 --- a/Train.cpp +++ b/Train.cpp @@ -478,11 +478,13 @@ PyObject *TTrain::GetTrainState() { PyDict_SetItemString( dict, "velocity", PyGetFloat( mover->Vel ) ); PyDict_SetItemString( dict, "tractionforce", PyGetFloat( mover->Ft ) ); PyDict_SetItemString( dict, "slipping_wheels", PyGetBool( mover->SlippingWheels ) ); + PyDict_SetItemString( dict, "sanding", PyGetBool( mover->SlippingWheels )); // electric current data PyDict_SetItemString( dict, "traction_voltage", PyGetFloat( mover->RunningTraction.TractionVoltage ) ); PyDict_SetItemString( dict, "voltage", PyGetFloat( mover->Voltage ) ); PyDict_SetItemString( dict, "im", PyGetFloat( mover->Im ) ); PyDict_SetItemString( dict, "fuse", PyGetBool( mover->FuseFlag ) ); + PyDict_SetItemString( dict, "epfuse", PyGetBool( mover->EpFuse )); // induction motor state data char* TXTT[ 10 ] = { "fd", "fdt", "fdb", "pd", "pdt", "pdb", "itothv", "1", "2", "3" }; char* TXTC[ 10 ] = { "fr", "frt", "frb", "pr", "prt", "prb", "im", "vm", "ihv", "uhv" }; @@ -522,6 +524,7 @@ PyObject *TTrain::GetTrainState() { PyDict_SetItemString( dict, ( std::string( "code_" ) + std::to_string( i + 1 ) ).c_str(), PyGetString( std::string( std::to_string( iUnits[ i ] ) + cCode[ i ] ).c_str() ) ); PyDict_SetItemString( dict, ( std::string( "car_name" ) + std::to_string( i + 1 ) ).c_str(), PyGetString( asCarName[ i ].c_str() ) ); + PyDict_SetItemString( dict, ( std::string( "slip_" ) + std::to_string( i + 1 )).c_str(), PyGetBool( bSlip[i]) ); } // ai state data auto const &driver = DynamicObject->Mechanik; @@ -3879,19 +3882,33 @@ if d = d->Prev(); // w drugą stronę też } } - else if (cKey == GLFW_KEY_RIGHT_BRACKET) - { - while (d) - { - d->Move(-100.0 * d->DirectionGet()); - d = d->Next(); // pozostałe też - } - d = DynamicObject->Prev(); - while (d) - { - d->Move(-100.0 * d->DirectionGet()); - d = d->Prev(); // w drugą stronę też - } + else if (cKey == GLFW_KEY_RIGHT_BRACKET) + { + while (d) + { + d->Move(-100.0 * d->DirectionGet()); + d = d->Next(); // pozostałe też + } + d = DynamicObject->Prev(); + while (d) + { + d->Move(-100.0 * d->DirectionGet()); + d = d->Prev(); // w drugą stronę też + } + } + else if (cKey == GLFW_KEY_TAB) + { + while (d) + { + d->MoverParameters->V+= d->DirectionGet()*2.78; + d = d->Next(); // pozostałe też + } + d = DynamicObject->Prev(); + while (d) + { + d->MoverParameters->V += d->DirectionGet()*2.78; + d = d->Prev(); // w drugą stronę też + } } } if (cKey == GLFW_KEY_MINUS) @@ -4176,11 +4193,12 @@ bool TTrain::Update( double const Deltatime ) bDoors[i][2] = (p->dDoorMoveL > 0.001); iDoorNo[i] = p->iAnimType[ANIM_DOORS]; iUnits[i] = iUnitNo; - cCode[i] = p->MoverParameters->TypeName[p->MoverParameters->TypeName.length()]; + cCode[i] = p->MoverParameters->TypeName[p->MoverParameters->TypeName.length()-1]; asCarName[i] = p->GetName(); bPants[iUnitNo - 1][0] = (bPants[iUnitNo - 1][0] || p->MoverParameters->PantFrontUp); bPants[iUnitNo - 1][1] = (bPants[iUnitNo - 1][1] || p->MoverParameters->PantRearUp); bComp[iUnitNo - 1][0] = (bComp[iUnitNo - 1][0] || p->MoverParameters->CompressorAllow); + bSlip[i] = p->MoverParameters->SlippingWheels; if (p->MoverParameters->CompressorSpeed > 0.00001) { bComp[iUnitNo - 1][1] = (bComp[iUnitNo - 1][1] || p->MoverParameters->CompressorFlag); @@ -4222,6 +4240,7 @@ bool TTrain::Update( double const Deltatime ) bDoors[i][0] = false; bDoors[i][1] = false; bDoors[i][2] = false; + bSlip[i] = false; iUnits[i] = 0; cCode[i] = 0; //'0'; asCarName[i] = ""; diff --git a/Train.h b/Train.h index c9c9e6d2..de3b00b4 100644 --- a/Train.h +++ b/Train.h @@ -464,6 +464,7 @@ public: // reszta może by?publiczna int iUnits[20]; // numer jednostki int iDoorNo[20]; // liczba drzwi char cCode[20]; // kod pojazdu + bool bSlip[20]; // poślizg kół pojazdu std::string asCarName[20]; // nazwa czlonu bool bMains[8]; // WSy float fCntVol[8]; // napiecie NN From fd06e2306a1b6b855fcce272f3733ddb373cc9f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Sun, 24 Sep 2017 20:20:18 +0200 Subject: [PATCH 5/5] Added wheel flats calculation and some small changes to induction motors --- Driver.cpp | 2 +- DynObj.cpp | 8 ++++---- McZapkie/MOVER.h | 2 ++ McZapkie/Mover.cpp | 35 ++++++++++++++++++++++++++--------- McZapkie/hamulce.cpp | 11 +++++++++-- Train.cpp | 6 +++--- World.cpp | 30 +++++++++++++++--------------- 7 files changed, 60 insertions(+), 34 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 12af005a..ee8d8e2d 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1707,7 +1707,7 @@ void TController::AutoRewident() } if (mvOccupied->TrainType == dt_EZT) { - fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 8 * fBrake_a1[BrakeAccTableSize]; + fAccThreshold = std::max(-fBrake_a0[BrakeAccTableSize] - 8 * fBrake_a1[BrakeAccTableSize], -0.75); fBrakeReaction = 0.25; } else if (ustaw > 16) diff --git a/DynObj.cpp b/DynObj.cpp index 2a5c9254..5a7f852c 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -2784,9 +2784,9 @@ bool TDynamicObject::Update(double dt, double dt1) 1000; // chwilowy max ED -> do rozdzialu sil FfulED = Min0R(p->MoverParameters->eimv[eimv_Fful], 0) * 1000; // chwilowy max ED -> do rozdzialu sil - FrED -= Min0R(p->MoverParameters->eimv[eimv_Fr], 0) * + FrED -= Min0R(p->MoverParameters->eimv[eimv_Fmax], 0) * 1000; // chwilowo realizowane ED -> do pneumatyki - Frj += Max0R(p->MoverParameters->eimv[eimv_Fr], 0) * + Frj += Max0R(p->MoverParameters->eimv[eimv_Fmax], 0) * 1000;// chwilowo realizowany napęd -> do utrzymującego masa += p->MoverParameters->TotalMass; osie += p->MoverParameters->NAxles; @@ -2880,10 +2880,10 @@ bool TDynamicObject::Update(double dt, double dt1) if ((FzEP[i] > 0.01) && (FzEP[i] > p->MoverParameters->TotalMass * p->MoverParameters->eimc[eimc_p_eped] + - Min0R(p->MoverParameters->eimv[eimv_Fr], 0) * 1000) && + Min0R(p->MoverParameters->eimv[eimv_Fmax], 0) * 1000) && (!PrzekrF[i])) { - float przek1 = -Min0R(p->MoverParameters->eimv[eimv_Fr], 0) * 1000 + + float przek1 = -Min0R(p->MoverParameters->eimv[eimv_Fmax], 0) * 1000 + FzEP[i] - p->MoverParameters->TotalMass * p->MoverParameters->eimc[eimc_p_eped] * 0.999; diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 19e14c7d..073ac37b 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -780,6 +780,7 @@ public: double Ftmax = 0.0; /*- dla lokomotyw z silnikami indukcyjnymi -*/ double eimc[26]; + bool EIMCLogForce; // static std::vector const eimc_labels; /*-dla wagonow*/ double MaxLoad = 0.0; /*masa w T lub ilosc w sztukach - ladownosc*/ @@ -823,6 +824,7 @@ public: double AccN = 0.0; //przyspieszenie normalne w [m/s^2] double AccV = 0.0; double nrot = 0.0; + double WheelFlat = 0.0; /*! rotacja kol [obr/s]*/ double EnginePower = 0.0; /*! chwilowa moc silnikow*/ double dL = 0.0; double Fb = 0.0; double Ff = 0.0; /*przesuniecie, sila hamowania i tarcia*/ diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index d7799a8b..06bc5830 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -3734,6 +3734,10 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer) Fb = -Fwheels*Sign(V); FTrain = 0; } + if (nrot < 0.1) + { + WheelFlat = sqrt(sqr(WheelFlat) + abs(Fwheels) / NAxles*Vel*0.000002); + } if (Sign(nrot * M_PI * WheelDiameter - V)*Sign(temp_nrot * M_PI * WheelDiameter - V) < 0) { SlippingWheels = false; @@ -4684,23 +4688,23 @@ double TMoverParameters::TractionForce(double dt) if ((abs((PosRatio + 9.66 * dizel_fill) * dmoment * 100) > 0.95 * Adhesive(RunningTrack.friction) * TotalMassxg)) { - PosRatio = 0; - tmp = 4; - Sandbox( true, range::local ); + //PosRatio = 0; + //tmp = 4; + //Sandbox( true, range::local ); } // przeciwposlizg if ((abs((PosRatio + 9.80 * dizel_fill) * dmoment * 100) > 0.95 * Adhesive(RunningTrack.friction) * TotalMassxg)) { - PosRatio = 0; - tmp = 9; - Sandbox( true, range::local ); + //PosRatio = 0; + //tmp = 9; + //Sandbox( true, range::local ); } // przeciwposlizg if ((SlippingWheels)) { // PosRatio = -PosRatio * 0; // serio -0 ??? PosRatio = 0; tmp = 9; - Sandbox( true, range::local ); + Sandbox( true, range::unit ); } // przeciwposlizg dizel_fill += Max0R(Min0R(PosRatio - dizel_fill, 0.1), -0.1) * 2 * @@ -4737,6 +4741,13 @@ double TMoverParameters::TractionForce(double dt) -Sign(V) * (DirAbsolute)*std::min( eimc[eimc_p_Ph] * 3.6 / (Vel != 0.0 ? Vel : 0.001), std::min(-eimc[eimc_p_Fh] * dizel_fill, eimv[eimv_FMAXMAX])); + double pr = dizel_fill; + if (EIMCLogForce) + pr = -log(1 - 4 * pr) / log(5); + eimv[eimv_Fr] = + -Sign(V) * (DirAbsolute)*std::min( + eimc[eimc_p_Ph] * 3.6 / (Vel != 0.0 ? Vel : 0.001), + std::min(-eimc[eimc_p_Fh] * pr, eimv[eimv_FMAXMAX])); //*Min0R(1,(Vel-eimc[eimc_p_Vh0])/(eimc[eimc_p_Vh1]-eimc[eimc_p_Vh0])) } else @@ -4748,9 +4759,13 @@ double TMoverParameters::TractionForce(double dt) eimv[eimv_Fmax] = eimv[eimv_Fful] * dizel_fill; // else // eimv[eimv_Fmax]:=Min0R(eimc[eimc_p_F0]*dizel_fill,eimv[eimv_Fful]); + double pr = dizel_fill; + if (EIMCLogForce) + pr = log(1 + 4 * pr) / log(5); + eimv[eimv_Fr] = eimv[eimv_Fful] * pr; } - eimv[eimv_ks] = eimv[eimv_Fmax] / eimv[eimv_FMAXMAX]; + eimv[eimv_ks] = eimv[eimv_Fr] / eimv[eimv_FMAXMAX]; eimv[eimv_df] = eimv[eimv_ks] * eimc[eimc_s_dfmax]; eimv[eimv_fp] = DirAbsolute * enrot * eimc[eimc_s_p] + eimv[eimv_df]; // do przemyslenia dzialanie pp z tmpV @@ -4921,7 +4936,7 @@ double TMoverParameters::v2n(void) n = V / (M_PI * WheelDiameter); // predkosc obrotowa wynikajaca z liniowej [obr/s] deltan = n - nrot; //"pochodna" prędkości obrotowej if (SlippingWheels) - if (std::abs(deltan) < 0.01) + if (std::abs(deltan) < 0.001) SlippingWheels = false; // wygaszenie poslizgu if (SlippingWheels) // nie ma zwiazku z predkoscia liniowa V { // McZapkie-221103: uszkodzenia kol podczas poslizgu @@ -7136,6 +7151,7 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) { if( asb == "Manual" ) { ASBType = 1; } else if( asb == "Automatic" ) { ASBType = 2; } + else if (asb == "Yes") { ASBType = 128; } } else { @@ -7384,6 +7400,7 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) { extract_value( eimc[ eimc_p_Imax ], "Imax", Input, "" ); extract_value( eimc[ eimc_p_abed ], "abed", Input, "" ); extract_value( eimc[ eimc_p_eped ], "edep", Input, "" ); + EIMCLogForce = ( extract_value( "eimclf", Input ) == "Yes" ); Flat = ( extract_value( "Flat", Input ) == "1" ); diff --git a/McZapkie/hamulce.cpp b/McZapkie/hamulce.cpp index 06e45445..a1156baf 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -1462,9 +1462,15 @@ double TEStED::GetPF( double const PP, double const dt, double const Vel ) // powtarzacz — podwojny zawor zwrotny temp = Max0R(LoadC * BCP / temp * Min0R(Max0R(1 - EDFlag, 0), 1), LBP); + double speed = 1; + if ((ASBP < 0.1) && ((BrakeStatus & b_asb) == b_asb)) + { + temp = 0; + speed = 3; + } if ((BrakeCyl->P() > temp)) - dv = -PFVd(BrakeCyl->P(), 0, 0.02 * SizeBC, temp) * dt; + dv = -PFVd(BrakeCyl->P(), 0, 0.02 * SizeBC * speed, temp) * dt; else if ((BrakeCyl->P() < temp)) dv = PFVa(BVP, BrakeCyl->P(), 0.02 * SizeBC, temp) * dt; else @@ -1995,7 +2001,8 @@ double TKE::GetPF( double const PP, double const dt, double const Vel ) // luzowanie CH // temp:=Max0R(BCP,LBP); IMP = Max0R(IMP / temp, Max0R(LBP, ASBP * int((BrakeStatus & b_asb) == b_asb))); - + if ((ASBP < 0.1) && ((BrakeStatus & b_asb) == b_asb)) + IMP = 0; // luzowanie CH if ((BCP > IMP + 0.005) || (Max0R(ImplsRes->P(), 8 * LBP) < 0.25)) dv = PFVd(BCP, 0, 0.05, IMP) * dt; diff --git a/Train.cpp b/Train.cpp index e6f4902b..a9aba82f 100644 --- a/Train.cpp +++ b/Train.cpp @@ -478,7 +478,7 @@ PyObject *TTrain::GetTrainState() { PyDict_SetItemString( dict, "velocity", PyGetFloat( mover->Vel ) ); PyDict_SetItemString( dict, "tractionforce", PyGetFloat( mover->Ft ) ); PyDict_SetItemString( dict, "slipping_wheels", PyGetBool( mover->SlippingWheels ) ); - PyDict_SetItemString( dict, "sanding", PyGetBool( mover->SlippingWheels )); + PyDict_SetItemString( dict, "sanding", PyGetBool( mover->SandDose )); // electric current data PyDict_SetItemString( dict, "traction_voltage", PyGetFloat( mover->RunningTraction.TractionVoltage ) ); PyDict_SetItemString( dict, "voltage", PyGetFloat( mover->Voltage ) ); @@ -4205,10 +4205,10 @@ bool TTrain::Update( double const Deltatime ) } if ((in < 8) && (p->MoverParameters->eimc[eimc_p_Pmax] > 1)) { - fEIMParams[1 + in][0] = p->MoverParameters->eimv[eimv_Fr]; + fEIMParams[1 + in][0] = p->MoverParameters->eimv[eimv_Fmax]; fEIMParams[1 + in][1] = Max0R(fEIMParams[1 + in][0], 0); fEIMParams[1 + in][2] = -Min0R(fEIMParams[1 + in][0], 0); - fEIMParams[1 + in][3] = p->MoverParameters->eimv[eimv_Fr] / + fEIMParams[1 + in][3] = p->MoverParameters->eimv[eimv_Fmax] / Max0R(p->MoverParameters->eimv[eimv_Fful], 1); fEIMParams[1 + in][4] = Max0R(fEIMParams[1 + in][3], 0); fEIMParams[1 + in][5] = -Min0R(fEIMParams[1 + in][3], 0); diff --git a/World.cpp b/World.cpp index 127a4aa6..f077fa2f 100644 --- a/World.cpp +++ b/World.cpp @@ -1061,12 +1061,12 @@ bool TWorld::Update() /* if (DebugModeFlag) if (Global::bActive) // nie przyspieszać, gdy jedzie w tle :) - if( Console::Pressed( GLFW_KEY_ESCAPE ) ) { + if (glfwGetKey(window, GLFW_KEY_PAUSE) == GLFW_PRESS) { // yB dodał przyspieszacz fizyki - Ground.Update(dt, n); - Ground.Update(dt, n); - Ground.Update(dt, n); - Ground.Update(dt, n); // 5 razy + Ground.Update(dt / updatecount, updatecount); + Ground.Update(dt / updatecount, updatecount); + Ground.Update(dt / updatecount, updatecount); + Ground.Update(dt / updatecount, updatecount); // 5 razy } */ // secondary fixed step simulation time routines @@ -1481,7 +1481,7 @@ TWorld::Update_UI() { uitextline2 += "; Ft: " + to_string( tmp->MoverParameters->Ft * 0.001f * tmp->MoverParameters->ActiveCab, 1 ) + ", Fb: " + to_string( tmp->MoverParameters->Fb * 0.001f, 1 ) - + ", Fr: " + to_string( tmp->MoverParameters->RunningTrack.friction, 2 ) + + ", Fr: " + to_string( tmp->MoverParameters->Adhesive(tmp->MoverParameters->RunningTrack.friction), 2 ) + ( tmp->MoverParameters->SlippingWheels ? " (!)" : "" ); uitextline2 += @@ -1680,15 +1680,15 @@ TWorld::Update_UI() { if( tmp == nullptr ) { break; } - - uitextline1 = - "vel: " + to_string( tmp->GetVelocity(), 2 ) + " km/h" + ( tmp->MoverParameters->SlippingWheels ? " (!)" : "" ) - + "; dist: " + to_string( tmp->MoverParameters->DistCounter, 2 ) + " km" - + "; pos: (" - + to_string( tmp->GetPosition().x, 2 ) + ", " - + to_string( tmp->GetPosition().y, 2 ) + ", " - + to_string( tmp->GetPosition().z, 2 ) - + ")"; + uitextline1 = + "vel: " + to_string(tmp->GetVelocity(), 2) + "/" + to_string(tmp->MoverParameters->nrot* M_PI * tmp->MoverParameters->WheelDiameter * 3.6, 2) + + " km/h" + (tmp->MoverParameters->SlippingWheels ? " (!)" : " ") + + "; dist: " + to_string(tmp->MoverParameters->DistCounter, 2) + " km" + + "; pos: (" + + to_string(tmp->GetPosition().x, 2) + ", " + + to_string(tmp->GetPosition().y, 2) + ", " + + to_string(tmp->GetPosition().z, 2) + "), PM=" + + to_string(tmp->MoverParameters->WheelFlat, 1) + " mm"; uitextline2 = "HamZ=" + to_string( tmp->MoverParameters->fBrakeCtrlPos, 1 )