diff --git a/Driver.cpp b/Driver.cpp index 585423ae..2a481489 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1793,7 +1793,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 92a8a6ef..492ca704 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -2713,9 +2713,9 @@ bool TDynamicObject::Update(double dt, double dt1) 1000; // chwilowy max ED -> do rozdzialu sil FfulED = std::min(p->MoverParameters->eimv[eimv_Fful], 0.0) * 1000; // chwilowy max ED -> do rozdzialu sil - FrED -= std::min(p->MoverParameters->eimv[eimv_Fr], 0.0) * + FrED -= std::min(p->MoverParameters->eimv[eimv_Fmax], 0.0) * 1000; // chwilowo realizowane ED -> do pneumatyki - Frj += std::max(p->MoverParameters->eimv[eimv_Fr], 0.0) * + Frj += std::max(p->MoverParameters->eimv[eimv_Fmax], 0.0) * 1000;// chwilowo realizowany napęd -> do utrzymującego masa += p->MoverParameters->TotalMass; osie += p->MoverParameters->NAxles; @@ -2814,10 +2814,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 da94f8c5..2d84007d 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -779,6 +779,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*/ @@ -821,6 +822,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 4bee3a02..4e899f3a 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -3752,14 +3752,23 @@ 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 (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) { @@ -4649,7 +4658,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; @@ -4700,11 +4709,11 @@ double TMoverParameters::TractionForce(double dt) if( ( SlippingWheels ) ) { PosRatio = 0; tmp = 9; - Sandbox( true, range::local ); + Sandbox( true, range::unit ); } // przeciwposlizg else { // switch sandbox off - Sandbox( false, range::local ); + Sandbox( false, range::unit ); } dizel_fill += Max0R(Min0R(PosRatio - dizel_fill, 0.1), -0.1) * 2 * @@ -4741,6 +4750,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 @@ -4752,9 +4768,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 @@ -4925,7 +4945,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 @@ -7149,6 +7169,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 { @@ -7397,6 +7418,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 8c76e06a..7951791b 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -1474,9 +1474,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 @@ -2018,7 +2024,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 67a641e6..c76f97ec 100644 --- a/Train.cpp +++ b/Train.cpp @@ -472,11 +472,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->SandDose )); // 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" }; @@ -516,6 +518,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; @@ -3281,19 +3284,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) @@ -3578,21 +3595,22 @@ 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->name(); 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); } 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); @@ -3624,6 +3642,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 6b077597..61ed0e00 100644 --- a/Train.h +++ b/Train.h @@ -470,6 +470,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 diff --git a/World.cpp b/World.cpp index b282fb90..d1c38aae 100644 --- a/World.cpp +++ b/World.cpp @@ -1423,7 +1423,7 @@ TWorld::Update_UI() { uitextline2 += "; Ft: " + to_string( vehicle->MoverParameters->Ft * 0.001f * vehicle->MoverParameters->ActiveCab, 1 ) + ", Fb: " + to_string( vehicle->MoverParameters->Fb * 0.001f, 1 ) - + ", Fr: " + to_string( vehicle->MoverParameters->RunningTrack.friction, 2 ) + + ", Fr: " + to_string( vehicle->MoverParameters->Adhesive( vehicle->MoverParameters->RunningTrack.friction ), 2 ) + ( vehicle->MoverParameters->SlippingWheels ? " (!)" : "" ); if( vehicle->Mechanik ) { @@ -1625,15 +1625,15 @@ TWorld::Update_UI() { if( vehicle == nullptr ) { break; } - - uitextline1 = - "vel: " + to_string( vehicle->GetVelocity(), 2 ) + " km/h" + ( vehicle->MoverParameters->SlippingWheels ? " (!)" : "" ) - + "; dist: " + to_string( vehicle->MoverParameters->DistCounter, 2 ) + " km" - + "; pos: (" - + to_string( vehicle->GetPosition().x, 2 ) + ", " - + to_string( vehicle->GetPosition().y, 2 ) + ", " - + to_string( vehicle->GetPosition().z, 2 ) - + ")"; + uitextline1 = + "vel: " + to_string(vehicle->GetVelocity(), 2) + "/" + to_string(vehicle->MoverParameters->nrot* M_PI * vehicle->MoverParameters->WheelDiameter * 3.6, 2) + + " km/h" + (vehicle->MoverParameters->SlippingWheels ? " (!)" : " ") + + "; dist: " + to_string(vehicle->MoverParameters->DistCounter, 2) + " km" + + "; pos: (" + + to_string(vehicle->GetPosition().x, 2) + ", " + + to_string(vehicle->GetPosition().y, 2) + ", " + + to_string(vehicle->GetPosition().z, 2) + "), PM=" + + to_string(vehicle->MoverParameters->WheelFlat, 1) + " mm"; uitextline2 = "HamZ=" + to_string( vehicle->MoverParameters->fBrakeCtrlPos, 2 )