16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-23 17:59:19 +02:00

Merge remote-tracking branch 'youby/master' into sim

This commit is contained in:
milek7
2020-11-16 23:17:37 +01:00
11 changed files with 364 additions and 44 deletions

View File

@@ -1992,8 +1992,8 @@ void TController::Activation()
} }
ControllingSet(); // utworzenie połączenia do sterowanego pojazdu (może się zmienić) - silnikowy dla EZT ControllingSet(); // utworzenie połączenia do sterowanego pojazdu (może się zmienić) - silnikowy dla EZT
if( ( mvOccupied->BrakeCtrlPosNo > 0 ) if( ( mvOccupied->BrakeCtrlPosNo > 0 )
&& ( ( mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic ) && ( ( BrakeSystem == TBrakeSystem::Pneumatic )
|| ( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) ) ) { || ( BrakeSystem == TBrakeSystem::ElectroPneumatic ) ) ) {
mvOccupied->LimPipePress = mvOccupied->PipePress; mvOccupied->LimPipePress = mvOccupied->PipePress;
mvOccupied->ActFlowSpeed = 0; mvOccupied->ActFlowSpeed = 0;
} }
@@ -2122,6 +2122,7 @@ void TController::AutoRewident()
} }
// potentially release manual brake // potentially release manual brake
d->MoverParameters->DecManualBrakeLevel( ManualBrakePosNo ); d->MoverParameters->DecManualBrakeLevel( ManualBrakePosNo );
d->MoverParameters->SpringBrake.Activate = false;
} }
d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła) d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła)
} }
@@ -2156,6 +2157,32 @@ void TController::AutoRewident()
fNominalAccThreshold = fAccThreshold; fNominalAccThreshold = fAccThreshold;
} }
bool fullep = false;
BrakeSystem = mvOccupied->BrakeSystem;
if (BrakeSystem == TBrakeSystem::ElectroPneumatic)
{
fullep = true;
if (pVehicles[end::front] != pVehicles[end::rear]) {
// more detailed version, will use manual braking also for coupled sets of controlled vehicles
auto *vehicle = pVehicles[end::front]; // start from first
while ((true == fullep)
&& (vehicle != nullptr)) {
// NOTE: we could simplify this by doing only check of the rear coupler, but this can be quite tricky in itself
// TODO: add easier ways to access front/rear coupler taking into account vehicle's direction
fullep =
(((vehicle->MoverParameters->Couplers[end::front].Connected == nullptr)
|| ((vehicle->MoverParameters->Couplers[end::front].CouplingFlag & coupling::control)
&& (vehicle->MoverParameters->Couplers[end::front].Connected->Power > -1)))
&& ((vehicle->MoverParameters->Couplers[end::rear].Connected == nullptr)
|| ((vehicle->MoverParameters->Couplers[end::rear].CouplingFlag & coupling::control)
&& (vehicle->MoverParameters->Couplers[end::rear].Connected->Power > -1))));
vehicle = vehicle->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła)
}
}
if (!fullep) BrakeSystem = TBrakeSystem::Pneumatic;
mvOccupied->EpFuseSwitch(fullep);
}
if( OrderCurrentGet() & ( Obey_train | Bank ) ) { if( OrderCurrentGet() & ( Obey_train | Bank ) ) {
// 4. Przeliczanie siły hamowania // 4. Przeliczanie siły hamowania
double const velstep = ( mvOccupied->Vmax*0.5 ) / BrakeAccTableSize; double const velstep = ( mvOccupied->Vmax*0.5 ) / BrakeAccTableSize;
@@ -2190,12 +2217,13 @@ void TController::AutoRewident()
0.25 ); 0.25 );
if( mvOccupied->TrainType == dt_EZT ) { if( mvOccupied->TrainType == dt_EZT ) {
int ep_factor = fullep ? 8 : 4;
if( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) { if( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) {
// HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors // HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors
fNominalAccThreshold = std::max( -0.60, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] ); fNominalAccThreshold = std::max( -0.60, -fBrake_a0[ BrakeAccTableSize ] - ep_factor * fBrake_a1[ BrakeAccTableSize ] );
} }
else { else {
fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] ); fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - ep_factor * fBrake_a1[ BrakeAccTableSize ] );
} }
fBrakeReaction = 0.25; fBrakeReaction = 0.25;
} }
@@ -2213,6 +2241,7 @@ void TController::AutoRewident()
} }
fAccThreshold = fNominalAccThreshold; fAccThreshold = fNominalAccThreshold;
} }
} }
double TController::ESMVelocity(bool Main) double TController::ESMVelocity(bool Main)
@@ -2379,7 +2408,10 @@ bool TController::CheckVehicles(TOrders user)
if( mvOccupied->LightsPosNo > 0 ) { if( mvOccupied->LightsPosNo > 0 ) {
pVehicle->SetLights(); pVehicle->SetLights();
} }
if (OrderCurrentGet() & (Shunt | Loose_shunt | Disconnect | Connect | Change_direction)) {
// kasowanie pamieci hamowania kontrolnego
DynamicBrakeTest = 0;
}
if (AIControllFlag) if (AIControllFlag)
{ // jeśli prowadzi komputer { // jeśli prowadzi komputer
if( true == TestFlag( OrderCurrentGet(), Obey_train ) ) { if( true == TestFlag( OrderCurrentGet(), Obey_train ) ) {
@@ -2964,7 +2996,9 @@ bool TController::ReleaseEngine() {
bool TController::IncBrake() bool TController::IncBrake()
{ // zwiększenie hamowania { // zwiększenie hamowania
bool OK = false; bool OK = false;
switch( mvOccupied->BrakeSystem ) { TBrakeSystem bs = ((BrakeSystem == TBrakeSystem::ElectroPneumatic) && (ForcePNBrake)) ?
TBrakeSystem::Pneumatic : BrakeSystem;
switch( bs ) {
case TBrakeSystem::Individual: { case TBrakeSystem::Individual: {
if( mvOccupied->LocalBrake == TLocalBrake::ManualBrake ) { if( mvOccupied->LocalBrake == TLocalBrake::ManualBrake ) {
OK = mvOccupied->IncManualBrakeLevel( 1 + static_cast<int>( std::floor( 0.5 + std::fabs( AccDesired ) ) ) ); OK = mvOccupied->IncManualBrakeLevel( 1 + static_cast<int>( std::floor( 0.5 + std::fabs( AccDesired ) ) ) );
@@ -2975,6 +3009,13 @@ bool TController::IncBrake()
break; break;
} }
case TBrakeSystem::Pneumatic: { case TBrakeSystem::Pneumatic: {
if (bs != mvOccupied->BrakeSystem)
{
while (mvOccupied->BrakeOpModeFlag > bom_PN)
{
mvOccupied->BrakeOpModeFlag >>= 1;
}
}
// NOTE: can't perform just test whether connected vehicle == nullptr, due to virtual couplers formed with nearby vehicles // NOTE: can't perform just test whether connected vehicle == nullptr, due to virtual couplers formed with nearby vehicles
bool standalone { true }; bool standalone { true };
if( ( mvOccupied->TrainType == dt_ET41 ) if( ( mvOccupied->TrainType == dt_ET41 )
@@ -3026,7 +3067,7 @@ bool TController::IncBrake()
//standalone = standalone && ( mvControlling->EIMCtrlType == 0 ); //standalone = standalone && ( mvControlling->EIMCtrlType == 0 );
if( true == standalone ) { if( true == standalone && false == ForcePNBrake ) {
if( mvControlling->EIMCtrlType > 0 ) { if( mvControlling->EIMCtrlType > 0 ) {
OK = IncBrakeEIM(); OK = IncBrakeEIM();
} }
@@ -3104,6 +3145,10 @@ bool TController::IncBrake()
break; break;
} }
case TBrakeSystem::ElectroPneumatic: { case TBrakeSystem::ElectroPneumatic: {
while ((mvOccupied->BrakeOpModeFlag << 1) <= mvOccupied->BrakeOpModes)
{
mvOccupied->BrakeOpModeFlag <<= 1;
}
if( mvOccupied->EngineType == TEngineType::ElectricInductionMotor ) { if( mvOccupied->EngineType == TEngineType::ElectricInductionMotor ) {
if (mvOccupied->BrakeHandle == TBrakeHandle::MHZ_EN57) { if (mvOccupied->BrakeHandle == TBrakeHandle::MHZ_EN57) {
if (mvOccupied->BrakeCtrlPos < mvOccupied->Handle->GetPos(bh_FB)) if (mvOccupied->BrakeCtrlPos < mvOccupied->Handle->GetPos(bh_FB))
@@ -3192,7 +3237,9 @@ bool TController::DecBrake()
bool OK = false; bool OK = false;
double deltaAcc = -1.0; double deltaAcc = -1.0;
double pos_diff = 1.0; double pos_diff = 1.0;
switch (mvOccupied->BrakeSystem) TBrakeSystem bs = BrakeSystem == TBrakeSystem::ElectroPneumatic && ForcePNBrake ?
TBrakeSystem::Pneumatic : BrakeSystem;
switch (bs)
{ {
case TBrakeSystem::Individual: case TBrakeSystem::Individual:
if (mvOccupied->LocalBrake == TLocalBrake::ManualBrake) if (mvOccupied->LocalBrake == TLocalBrake::ManualBrake)
@@ -3926,7 +3973,7 @@ void TController::SpeedCntrl(double DesiredSpeed)
void TController::SetTimeControllers() void TController::SetTimeControllers()
{ {
//1. Check the type of Main Brake Handle //1. Check the type of Main Brake Handle
if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic) if (BrakeSystem == TBrakeSystem::Pneumatic || ForcePNBrake)
{ {
if (mvOccupied->Handle->Time) if (mvOccupied->Handle->Time)
{ {
@@ -3942,7 +3989,8 @@ void TController::SetTimeControllers()
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_NP)); mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_NP));
} }
if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) mvOccupied->BrakeLevelSet(BrakeCtrlPosition); if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) mvOccupied->BrakeLevelSet(BrakeCtrlPosition);
if (mvOccupied->BrakeHandle == TBrakeHandle::MHZ_K8P) if ((mvOccupied->BrakeHandle == TBrakeHandle::MHZ_K8P)
|| (mvOccupied->BrakeHandle == TBrakeHandle::MHZ_EN57))
{ {
if (BrakeCtrlPosition == 0) if (BrakeCtrlPosition == 0)
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP)); mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP));
@@ -4127,11 +4175,11 @@ void TController::SetTimeControllers()
void TController::CheckTimeControllers() void TController::CheckTimeControllers()
{ {
//1. Check the type of Main Brake Handle //1. Check the type of Main Brake Handle
if (mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic && mvOccupied->Handle->TimeEP) if (BrakeSystem == TBrakeSystem::ElectroPneumatic && mvOccupied->Handle->TimeEP && !ForcePNBrake)
{ {
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EPN)); mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EPN));
} }
if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic && mvOccupied->Handle->Time) if ((BrakeSystem == TBrakeSystem::Pneumatic || ForcePNBrake) && mvOccupied->Handle->Time)
{ {
if (BrakeCtrlPosition > 0) if (BrakeCtrlPosition > 0)
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_MB)); mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_MB));
@@ -5907,7 +5955,7 @@ TController::UpdateSituation(double dt) {
// powino zostać wyłączone) // powino zostać wyłączone)
// WriteLog("Zahamowanie składu"); // WriteLog("Zahamowanie składu");
AccDesired = std::min( AccDesired, -0.9 ); // HACK: make sure the ai doesn't try to release the brakes to accelerate AccDesired = std::min( AccDesired, -0.9 ); // HACK: make sure the ai doesn't try to release the brakes to accelerate
if( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) { if( BrakeSystem == TBrakeSystem::ElectroPneumatic ) {
mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_EPB ) ); mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_EPB ) );
} }
else { else {
@@ -5919,11 +5967,11 @@ TController::UpdateSituation(double dt) {
// TODO: zabezpieczenie przed dziwnymi CHK do czasu wyjaśnienia sensu 0 oraz -1 w tym miejscu // TODO: zabezpieczenie przed dziwnymi CHK do czasu wyjaśnienia sensu 0 oraz -1 w tym miejscu
p = 3.9; p = 3.9;
} }
if (mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ? if (BrakeSystem == TBrakeSystem::ElectroPneumatic ?
mvOccupied->BrakePress > 2 : mvOccupied->BrakePress > 2 :
mvOccupied->PipePress < p + 0.1) mvOccupied->PipePress < p + 0.1)
{ // jeśli w miarę został zahamowany (ciśnienie mniejsze niż podane na pozycji 3, zwyle 0.37) { // jeśli w miarę został zahamowany (ciśnienie mniejsze niż podane na pozycji 3, zwyle 0.37)
if( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) { if( BrakeSystem == TBrakeSystem::ElectroPneumatic ) {
// wyłączenie EP, gdy wystarczy (może nie być potrzebne, bo na początku jest) // wyłączenie EP, gdy wystarczy (może nie być potrzebne, bo na początku jest)
mvOccupied->BrakeLevelSet( 0 ); mvOccupied->BrakeLevelSet( 0 );
} }
@@ -6497,6 +6545,61 @@ TController::UpdateSituation(double dt) {
} }
} }
// koniec predkosci aktualnej // koniec predkosci aktualnej
if (Global.DynamicBrakeTest && AIControllFlag)
{
// hamowanie kontrolne
if ((OrderCurrentGet() & Obey_train) && (DynamicBrakeTest == 0) && (vel < VelDesired)
&& (AccDesired > 0) && (TrainParams.TTVmax >= 10.0) && (primary())
&& (vel > std::min(TrainParams.TTVmax - 2.0, 58.0)))
{
DynamicBrakeTest = 1;
DBT_BrakingTime = ElapsedTime;
}
switch (DynamicBrakeTest)
{
case 1:
AccDesired = -0.06;
if (ElapsedTime - DBT_BrakingTime > 1)
{
ForcePNBrake = true;
mvOccupied->EpFuseSwitch(false);
DynamicBrakeTest = 2;
}
break;
case 2:
if (ElapsedTime - DBT_BrakingTime > 2)
{
DBT_BrakingTime = ElapsedTime;
DBT_VelocityBrake = vel;
DBT_VelocityRelease = vel - 8.0;
DynamicBrakeTest = 3;
}
AccDesired = -0.06;
break;
case 3:
AccDesired = clamp(-AbsAccS, fAccThreshold * 1.01, fAccThreshold * 1.21);
if (vel <= DBT_VelocityRelease)
{
DynamicBrakeTest = 4;
DBT_BrakingTime = ElapsedTime - DBT_BrakingTime;
DBT_MidPointAcc = AbsAccS;
DBT_ReleasingTime = ElapsedTime;
}
break;
case 4:
if (fReady < 0.5)
{
if (BrakeSystem == TBrakeSystem::ElectroPneumatic) {
mvOccupied->EpFuseSwitch(true);
}
ForcePNBrake = false;
DynamicBrakeTest = 5;
DBT_ReleasingTime = ElapsedTime - DBT_ReleasingTime;
DBT_VelocityFinish = vel;
}
break;
}
}
// last step sanity check, until the whole calculation is straightened out // last step sanity check, until the whole calculation is straightened out
AccDesired = std::min( AccDesired, AccPreferred ); AccDesired = std::min( AccDesired, AccPreferred );
@@ -6594,7 +6697,7 @@ TController::UpdateSituation(double dt) {
ReactionTime = 0.25; ReactionTime = 0.25;
} }
} }
if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic) { if (BrakeSystem == TBrakeSystem::Pneumatic) {
// napełnianie uderzeniowe // napełnianie uderzeniowe
if( ( mvOccupied->BrakeHandle == TBrakeHandle::FV4a ) if( ( mvOccupied->BrakeHandle == TBrakeHandle::FV4a )
|| ( mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P ) || ( mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P )
@@ -6763,7 +6866,7 @@ TController::UpdateSituation(double dt) {
DecSpeed(); DecSpeed();
} }
} }
if( mvOccupied->TrainType == dt_EZT ) { if( (mvOccupied->TrainType == dt_EZT) && (!ForcePNBrake) ) {
// właściwie, to warunek powinien być na działający EP // właściwie, to warunek powinien być na działający EP
// Ra: to dobrze hamuje EP w EZT // Ra: to dobrze hamuje EP w EZT
// HACK: when going downhill be more responsive to desired deceleration // HACK: when going downhill be more responsive to desired deceleration
@@ -7710,6 +7813,7 @@ void TController::ControllingSet()
// dzięki temu będzie wirtualna kabina w silnikowym, działająca w rozrządczym // dzięki temu będzie wirtualna kabina w silnikowym, działająca w rozrządczym
// w plikach FIZ zostały zgubione ujemne maski sprzęgów, stąd problemy z EZT // w plikach FIZ zostały zgubione ujemne maski sprzęgów, stąd problemy z EZT
mvOccupied = pVehicle->MoverParameters; // domyślny skrót do obiektu parametrów mvOccupied = pVehicle->MoverParameters; // domyślny skrót do obiektu parametrów
BrakeSystem = mvOccupied->BrakeSystem; // domyślny sposób hamowania
mvControlling = pVehicle->FindPowered()->MoverParameters; // poszukiwanie członu sterowanego mvControlling = pVehicle->FindPowered()->MoverParameters; // poszukiwanie członu sterowanego
{ {
auto *lookup { pVehicle->FindPantographCarrier() }; auto *lookup { pVehicle->FindPantographCarrier() };

View File

@@ -356,6 +356,16 @@ private:
double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI
double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
double BrakeChargingCooldown{}; // prevents the ai from trying to charge the train brake too frequently double BrakeChargingCooldown{}; // prevents the ai from trying to charge the train brake too frequently
TBrakeSystem BrakeSystem = TBrakeSystem::Individual; //type of main brake
bool ForcePNBrake = false; //is it necessary to use PN brake instead of EP brake
int DynamicBrakeTest = 0; //is it necessary to make brake test while driving
double DBT_VelocityBrake = 0;
double DBT_VelocityRelease = 0;
double DBT_VelocityFinish = 0;
double DBT_BrakingTime = 0;
double DBT_ReleasingTime = 0;
double DBT_MidPointAcc = 0;
int StaticBrakeTest = 0; //is it necessary to make brake test while standing
double LastReactionTime = 0.0; double LastReactionTime = 0.0;
double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi
double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations

View File

@@ -3131,6 +3131,7 @@ bool TDynamicObject::Update(double dt, double dt1)
p->MoverParameters->MED_Vref) * p->MoverParameters->MED_Vref) *
1000; // sila hamowania pn 1000; // sila hamowania pn
FmaxED += ((p->MoverParameters->Mains) && (p->MoverParameters->DirActive != 0) && FmaxED += ((p->MoverParameters->Mains) && (p->MoverParameters->DirActive != 0) &&
(p->MoverParameters->InvertersRatio == 1.0) &&
(p->MoverParameters->eimc[eimc_p_Fh] * p->MoverParameters->NPoweredAxles > (p->MoverParameters->eimc[eimc_p_Fh] * p->MoverParameters->NPoweredAxles >
0) ? 0) ?
p->MoverParameters->eimc[eimc_p_Fh] * 1000 : p->MoverParameters->eimc[eimc_p_Fh] * 1000 :
@@ -3152,12 +3153,13 @@ bool TDynamicObject::Update(double dt, double dt1)
RapidMult = MoverParameters->RapidMult; RapidMult = MoverParameters->RapidMult;
auto const amax = RapidMult * std::min(FmaxPN / masamax, MoverParameters->MED_amax); auto const amax = RapidMult * std::min(FmaxPN / masamax, MoverParameters->MED_amax);
auto const doorisopen { auto doorisopen {
( false == MoverParameters->Doors.instances[ side::left ].is_closed ) ( false == MoverParameters->Doors.instances[ side::left ].is_closed )
|| ( false == MoverParameters->Doors.instances[ side::right ].is_closed ) || ( false == MoverParameters->Doors.instances[ side::right ].is_closed )
|| ( MoverParameters->Doors.permit_needed || ( MoverParameters->Doors.permit_needed
&& ( MoverParameters->Doors.instances[ side::left ].open_permit && ( MoverParameters->Doors.instances[ side::left ].open_permit
|| MoverParameters->Doors.instances[ side::right ].open_permit ) ) }; || MoverParameters->Doors.instances[ side::right ].open_permit ) ) };
doorisopen &= !(MoverParameters->ReleaseParkingBySpringBrakeWhenDoorIsOpen && MoverParameters->SpringBrake.IsActive);
if ((MoverParameters->Vel < 0.5) && (eimic < 0 || doorisopen || MoverParameters->Hamulec->GetEDBCP())) if ((MoverParameters->Vel < 0.5) && (eimic < 0 || doorisopen || MoverParameters->Hamulec->GetEDBCP()))
{ {
@@ -3184,7 +3186,7 @@ bool TDynamicObject::Update(double dt, double dt1)
{ {
Fzad = std::min(LBR * FmaxED, FfulED); Fzad = std::min(LBR * FmaxED, FfulED);
} }
if (((MoverParameters->ShuntMode) && (eimic <= 0)) /*|| if (((MoverParameters->ShuntMode) && (eimic <= 0) || (doorisopen)) /*||
(MoverParameters->V * MoverParameters->DirAbsolute < -0.2)*/) (MoverParameters->V * MoverParameters->DirAbsolute < -0.2)*/)
{ {
auto const sbd { ( ( MoverParameters->SpringBrake.IsActive && MoverParameters->ReleaseParkingBySpringBrake ) ? 0.0 : MoverParameters->StopBrakeDecc ) }; auto const sbd { ( ( MoverParameters->SpringBrake.IsActive && MoverParameters->ReleaseParkingBySpringBrake ) ? 0.0 : MoverParameters->StopBrakeDecc ) };
@@ -7243,6 +7245,9 @@ TDynamicObject::update_shake( double const Timedelta ) {
IsHunting = ( huntingamount > 0.025 ); IsHunting = ( huntingamount > 0.025 );
} }
if (FreeFlyModeFlag)
shakevector *= 0;
auto const iVel { std::min( GetVelocity(), 150.0 ) }; auto const iVel { std::min( GetVelocity(), 150.0 ) };
if( iVel > 0.5 ) { if( iVel > 0.5 ) {
// acceleration-driven base shake // acceleration-driven base shake

View File

@@ -678,6 +678,12 @@ global_settings::ConfigParse(cParser &Parser) {
Parser.getTokens(1, false); Parser.getTokens(1, false);
Parser >> iHiddenEvents; Parser >> iHiddenEvents;
} }
else if (token == "dynamicbraketest")
{
// enable dynamic brake tests made by AI drivers
Parser.getTokens();
Parser >> DynamicBrakeTest;
}
else if (token == "pause") else if (token == "pause")
{ {
// czy po wczytaniu ma być pauza? // czy po wczytaniu ma być pauza?

View File

@@ -103,6 +103,7 @@ struct global_settings {
bool bRollFix{ true }; // czy wykonać przeliczanie przechyłki bool bRollFix{ true }; // czy wykonać przeliczanie przechyłki
bool bJoinEvents{ false }; // czy grupować eventy o tych samych nazwach bool bJoinEvents{ false }; // czy grupować eventy o tych samych nazwach
int iHiddenEvents{ 1 }; // czy łączyć eventy z torami poprzez nazwę toru int iHiddenEvents{ 1 }; // czy łączyć eventy z torami poprzez nazwę toru
bool DynamicBrakeTest { false }; //enable dynamic brake tests made by AI drivers
// ui // ui
int PythonScreenUpdateRate{ 200 }; // delay between python-based screen updates, in milliseconds int PythonScreenUpdateRate{ 200 }; // delay between python-based screen updates, in milliseconds
int iTextMode{ 0 }; // tryb pracy wyświetlacza tekstowego int iTextMode{ 0 }; // tryb pracy wyświetlacza tekstowego

View File

@@ -779,6 +779,16 @@ struct speed_control {
double PowerDownSpeed = 1000; double PowerDownSpeed = 1000;
}; };
struct inverter {
double Freal = 0.0;
double Request = 0.0;
bool IsActive = true;
bool Activate = true;
bool Error = false;
bool Failure_Drive = false;
bool Failure_Const = false;
};
class TMoverParameters class TMoverParameters
{ // Ra: wrapper na kod pascalowy, przejmujący jego funkcje Q: 20160824 - juz nie wrapper a klasa bazowa :) { // Ra: wrapper na kod pascalowy, przejmujący jego funkcje Q: 20160824 - juz nie wrapper a klasa bazowa :)
private: private:
@@ -1121,6 +1131,11 @@ public:
double Spg = 0.0; double Spg = 0.0;
double MinCompressor = 0.0; double MinCompressor = 0.0;
double MaxCompressor = 0.0; double MaxCompressor = 0.0;
double MinCompressor_cabA = 0.0;
double MaxCompressor_cabA = 0.0;
double MinCompressor_cabB = 0.0;
double MaxCompressor_cabB = 0.0;
bool CabDependentCompressor = false;
double CompressorSpeed = 0.0; double CompressorSpeed = 0.0;
int CompressorList[4][9]; // pozycje świateł, przód - tył, 1 .. 16 int CompressorList[4][9]; // pozycje świateł, przód - tył, 1 .. 16
double EmergencyValveOn = 0.0; double EmergencyValveOn = 0.0;
@@ -1149,6 +1164,9 @@ public:
bool MBrake = false; /*Czy jest hamulec reczny*/ bool MBrake = false; /*Czy jest hamulec reczny*/
double StopBrakeDecc = 0.0; double StopBrakeDecc = 0.0;
bool ReleaseParkingBySpringBrake { false }; bool ReleaseParkingBySpringBrake { false };
bool ReleaseParkingBySpringBrakeWhenDoorIsOpen{ false };
bool SpringBrakeCutsOffDrive { true };
double SpringBrakeDriveEmergencyVel { -1 };
TSecuritySystem SecuritySystem; TSecuritySystem SecuritySystem;
int EmergencyBrakeWarningSignal{ 0 }; // combined with basic WarningSignal when manual emergency brake is active int EmergencyBrakeWarningSignal{ 0 }; // combined with basic WarningSignal when manual emergency brake is active
TUniversalCtrlTable UniCtrlList; /*lista pozycji uniwersalnego nastawnika*/ TUniversalCtrlTable UniCtrlList; /*lista pozycji uniwersalnego nastawnika*/
@@ -1279,6 +1297,9 @@ public:
bool EIMCLogForce = false; // bool EIMCLogForce = false; //
static std::vector<std::string> const eimc_labels; static std::vector<std::string> const eimc_labels;
double InverterFrequency { 0.0 }; // current frequency of power inverters double InverterFrequency { 0.0 }; // current frequency of power inverters
int InvertersNo = 0; // number of inverters
double InvertersRatio = 0.0;
std::vector<inverter> Inverters; //all inverters
/* -dla pojazdów z blendingiem EP/ED (MED) */ /* -dla pojazdów z blendingiem EP/ED (MED) */
double MED_Vmax = 0; // predkosc maksymalna dla obliczen chwilowej sily hamowania EP w MED double MED_Vmax = 0; // predkosc maksymalna dla obliczen chwilowej sily hamowania EP w MED
double MED_Vmin = 0; // predkosc minimalna dla obliczen chwilowej sily hamowania EP w MED double MED_Vmin = 0; // predkosc minimalna dla obliczen chwilowej sily hamowania EP w MED

View File

@@ -3891,7 +3891,7 @@ bool TMoverParameters::SwitchEPBrake(int state)
if ((BrakeHandle == TBrakeHandle::St113) && (CabOccupied != 0)) if ((BrakeHandle == TBrakeHandle::St113) && (CabOccupied != 0))
{ {
if (state > 0) if (state > 0)
temp = Handle->GetCP(); // TODO: przetlumaczyc temp = Handle->GetEP(); // TODO: przetlumaczyc
else else
temp = 0; temp = 0;
Hamulec->SetEPS(temp); Hamulec->SetEPS(temp);
@@ -4060,6 +4060,20 @@ void TMoverParameters::CompressorCheck(double dt) {
return; return;
} }
if (CabDependentCompressor)
{
if (CabActive > 0)
{
MinCompressor = MinCompressor_cabA;
MaxCompressor = MaxCompressor_cabA;
}
if (CabActive < 0)
{
MinCompressor = MinCompressor_cabB;
MaxCompressor = MaxCompressor_cabB;
}
}
//EmergencyValve //EmergencyValve
EmergencyValveOpen = (Compressor > (EmergencyValveOpen ? EmergencyValveOff : EmergencyValveOn)); EmergencyValveOpen = (Compressor > (EmergencyValveOpen ? EmergencyValveOff : EmergencyValveOn));
if (EmergencyValveOpen) { if (EmergencyValveOpen) {
@@ -4300,7 +4314,10 @@ void TMoverParameters::UpdatePipePressure(double dt)
|| ( true == AlarmChainFlag ) || ( true == AlarmChainFlag )
|| (( true == EIMCtrlEmergency) || (( true == EIMCtrlEmergency)
&& (LocalBrakePosA >= 1.0)) && (LocalBrakePosA >= 1.0))
|| SecuritySystem.is_braking())) || SecuritySystem.is_braking())
|| ( ( SpringBrakeDriveEmergencyVel >= 0 )
&& ( Vel > SpringBrakeDriveEmergencyVel )
&& ( SpringBrake.IsActive ) ) )
/* /*
// NOTE: disabled because 32 is 'load destroyed' flag, what does this have to do with emergency brake? // NOTE: disabled because 32 is 'load destroyed' flag, what does this have to do with emergency brake?
// (if it's supposed to be broken coupler, such event sets alarmchainflag instead when appropriate) // (if it's supposed to be broken coupler, such event sets alarmchainflag instead when appropriate)
@@ -4431,7 +4448,7 @@ void TMoverParameters::UpdatePipePressure(double dt)
&& (DirActive != 0) && (DirActive != 0)
&& (EpFuse)) // tu powinien byc jeszcze bezpiecznik EP i baterie - && (EpFuse)) // tu powinien byc jeszcze bezpiecznik EP i baterie -
// temp = (Handle as TFVel6).GetCP // temp = (Handle as TFVel6).GetCP
temp = Handle->GetCP(); temp = Handle->GetEP();
else else
temp = 0.0; temp = 0.0;
@@ -4807,6 +4824,11 @@ void TMoverParameters::ComputeTotalForce(double dt) {
Power > 0 ? Power > 0 ?
TractionForce( dt ) : TractionForce( dt ) :
0 ); 0 );
double FT_factor = 1.0;
if (EngineType == TEngineType::ElectricInductionMotor && InvertersRatio > 0.0) {
FT_factor = 1.0 / InvertersRatio;
FTrain *= FT_factor;
}
Fb = BrakeForce(RunningTrack); Fb = BrakeForce(RunningTrack);
// poslizg // poslizg
@@ -4861,6 +4883,7 @@ void TMoverParameters::ComputeTotalForce(double dt) {
FStand += Fb; FStand += Fb;
// doliczenie składowej stycznej grawitacji // doliczenie składowej stycznej grawitacji
FTrain /= FT_factor;
FTrain += TotalMassxg * RunningShape.dHtrack; FTrain += TotalMassxg * RunningShape.dHtrack;
//!niejawne przypisanie zmiennej! //!niejawne przypisanie zmiennej!
FTotal = FTrain - Sign(V) * FStand; FTotal = FTrain - Sign(V) * FStand;
@@ -5925,6 +5948,12 @@ double TMoverParameters::TractionForce( double dt ) {
case TEngineType::ElectricInductionMotor: case TEngineType::ElectricInductionMotor:
{ {
if( true == Mains && !SecuritySystem.is_engine_blocked() ) { if( true == Mains && !SecuritySystem.is_engine_blocked() ) {
double ActiveInverters = 0.0;
for (auto &inv : Inverters) {
if (inv.IsActive)
ActiveInverters += 1.0;
}
InvertersRatio = ActiveInverters / (double)InvertersNo;
//tempomat //tempomat
if (ScndCtrlPosNo == 4 && SpeedCtrlTypeTime) if (ScndCtrlPosNo == 4 && SpeedCtrlTypeTime)
{ {
@@ -6020,7 +6049,7 @@ double TMoverParameters::TractionForce( double dt ) {
PosRatio *= 0.9; PosRatio *= 0.9;
Hamulec->SetED(Max0R(0.0, std::min(PosRatio, 1.0))); //ustalenie stopnia zmniejszenia ciśnienia Hamulec->SetED(Max0R(0.0, std::min(PosRatio, 1.0))); //ustalenie stopnia zmniejszenia ciśnienia
// ustalanie siły hamowania ED // ustalanie siły hamowania ED
if ((Hamulec->GetEDBCP() > 0.25) && (eimc[eimc_p_abed] < 0.001)) //jeśli PN wyłącza ED if ((Hamulec->GetEDBCP() > 0.25) && (eimc[eimc_p_abed] < 0.001) || (ActiveInverters < InvertersNo)) //jeśli PN wyłącza ED
{ {
PosRatio = 0; PosRatio = 0;
eimv[eimv_Fzad] = 0; eimv[eimv_Fzad] = 0;
@@ -6066,6 +6095,11 @@ double TMoverParameters::TractionForce( double dt ) {
// switch sandbox off // switch sandbox off
SandboxAuto( false, range_t::unit ); SandboxAuto( false, range_t::unit );
} }
if (ActiveInverters == 0.0)
{
PosRatio = 0;
eimv_pr = 0;
}
eimv_pr += Max0R(Min0R(PosRatio - eimv_pr, 0.02), -0.02) * 12 * eimv_pr += Max0R(Min0R(PosRatio - eimv_pr, 0.02), -0.02) * 12 *
(tmp /*2{+4*byte(PosRatio<eimv_pr)*/) * (tmp /*2{+4*byte(PosRatio<eimv_pr)*/) *
@@ -6116,6 +6150,8 @@ double TMoverParameters::TractionForce( double dt ) {
-Sign(V) * (DirAbsolute)*std::min( -Sign(V) * (DirAbsolute)*std::min(
eimc[eimc_p_Ph] * 3.6 / (Vel != 0.0 ? Vel : 0.001), eimc[eimc_p_Ph] * 3.6 / (Vel != 0.0 ? Vel : 0.001),
std::min(-eimc[eimc_p_Fh] * pr, eimv[eimv_FMAXMAX])); std::min(-eimc[eimc_p_Fh] * pr, eimv[eimv_FMAXMAX]));
if (InvertersRatio < 1.0)
eimv[eimv_Fful] = 0;
//*Min0R(1,(Vel-eimc[eimc_p_Vh0])/(eimc[eimc_p_Vh1]-eimc[eimc_p_Vh0])) //*Min0R(1,(Vel-eimc[eimc_p_Vh0])/(eimc[eimc_p_Vh1]-eimc[eimc_p_Vh0]))
} }
else else
@@ -6132,7 +6168,11 @@ double TMoverParameters::TractionForce( double dt ) {
pr = log(1 + 4 * pr) / log(5); pr = log(1 + 4 * pr) / log(5);
eimv[eimv_Fr] = eimv[eimv_Fful] * pr; eimv[eimv_Fr] = eimv[eimv_Fful] * pr;
} }
for (auto &inv : Inverters) {
inv.Request = inv.IsActive ? eimv_pr : 0.0;
inv.Error = inv.Failure_Const || (inv.Failure_Drive && inv.Request != 0);
inv.IsActive = inv.Activate && !inv.Error;
}
eimv[eimv_ks] = eimv[eimv_Fr] / eimv[eimv_FMAXMAX]; eimv[eimv_ks] = eimv[eimv_Fr] / eimv[eimv_FMAXMAX];
eimv[eimv_df] = eimv[eimv_ks] * eimc[eimc_s_dfmax]; 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 eimv[eimv_fp] = DirAbsolute * enrot * eimc[eimc_s_p] + eimv[eimv_df]; // do przemyslenia dzialanie pp z tmpV
@@ -6146,8 +6186,8 @@ double TMoverParameters::TractionForce( double dt ) {
eimv[eimv_Ic] = (eimv[eimv_fp] - DirAbsolute * enrot * eimc[eimc_s_p]) * eimc[eimc_s_dfic] * eimv[eimv_pole]; eimv[eimv_Ic] = (eimv[eimv_fp] - DirAbsolute * enrot * eimc[eimc_s_p]) * eimc[eimc_s_dfic] * eimv[eimv_pole];
eimv[eimv_If] = eimv[eimv_Ic] * eimc[eimc_s_icif]; eimv[eimv_If] = eimv[eimv_Ic] * eimc[eimc_s_icif];
eimv[eimv_M] = eimv[eimv_pole] * eimv[eimv_Ic] * eimc[eimc_s_cim]; eimv[eimv_M] = eimv[eimv_pole] * eimv[eimv_Ic] * eimc[eimc_s_cim];
eimv[eimv_Ipoj] = (eimv[eimv_Ic] * NPoweredAxles * eimv[eimv_U]) / (EngineVoltage - eimc[eimc_f_DU]) + eimc[eimc_f_I0]; eimv[eimv_Ipoj] = (eimv[eimv_Ic] * NPoweredAxles * InvertersRatio * eimv[eimv_U]) / (EngineVoltage - eimc[eimc_f_DU]) + eimc[eimc_f_I0];
eimv[eimv_Pm] = DirActive * eimv[eimv_M] * NPoweredAxles * enrot * Pirazy2 / 1000; eimv[eimv_Pm] = DirActive * eimv[eimv_M] * NPoweredAxles * InvertersRatio * enrot * Pirazy2 / 1000;
eimv[eimv_Pe] = eimv[eimv_Ipoj] * EngineVoltage / 1000; eimv[eimv_Pe] = eimv[eimv_Ipoj] * EngineVoltage / 1000;
eimv[eimv_eta] = eimv[eimv_Pm] / eimv[eimv_Pe]; eimv[eimv_eta] = eimv[eimv_Pm] / eimv[eimv_Pe];
@@ -6188,11 +6228,15 @@ double TMoverParameters::TractionForce( double dt ) {
Mm = eimv[eimv_M] * DirAbsolute; Mm = eimv[eimv_M] * DirAbsolute;
Mw = Mm * Transmision.Ratio * Transmision.Efficiency; Mw = Mm * Transmision.Ratio * Transmision.Efficiency;
Fw = Mw * 2.0 / WheelDiameter; Fw = Mw * 2.0 / WheelDiameter;
Ft = Fw * NPoweredAxles; Ft = Fw * NPoweredAxles * InvertersRatio;
eimv[eimv_Fr] = DirAbsolute * Ft / 1000; eimv[eimv_Fr] = DirAbsolute * Ft / 1000;
} // mains } // mains
else else
{ {
for (auto &inv : Inverters) {
inv.Freal = 0.0;
inv.IsActive = false;
}
Im = 0.0; Im = 0.0;
Mm = 0.0; Mm = 0.0;
Mw = 0.0; Mw = 0.0;
@@ -7080,11 +7124,27 @@ void TMoverParameters::CheckEIMIC(double dt)
auto const eimicpowerenabled { auto const eimicpowerenabled {
( ( true == Mains ) || ( Power == 0.0 ) ) ( ( true == Mains ) || ( Power == 0.0 ) )
&& ( ( Doors.instances[ side::left ].open_permit == false ) && ( !SpringBrake.IsActive || !SpringBrakeCutsOffDrive )
&& ( Doors.instances[ side::right ].open_permit == false ) )
&& ( !SpringBrake.IsActive )
&& ( !LockPipe ) }; && ( !LockPipe ) };
eimic = clamp(eimic, -1.0, eimicpowerenabled ? 1.0 : 0.0); auto const eimicdoorenabled {
(SpringBrake.IsActive && ReleaseParkingBySpringBrakeWhenDoorIsOpen)
};
double eimic_max = 0.0;
if ((Doors.instances[side::left].open_permit == false)
&& (Doors.instances[side::right].open_permit == false)) {
if (eimicpowerenabled) {
eimic_max = 1.0;
}
else {
eimic_max = 0.001;
}
}
else {
if (eimicdoorenabled) {
eimic_max = 0.001;
}
}
eimic = clamp(eimic, -1.0, eimicpowerenabled ? eimic_max : 0.0);
} }
void TMoverParameters::CheckSpeedCtrl(double dt) void TMoverParameters::CheckSpeedCtrl(double dt)
@@ -9769,6 +9829,8 @@ void TMoverParameters::LoadFIZ_Brake( std::string const &line ) {
*/ */
extract_value( MinCompressor, "MinCP", line, "" ); extract_value( MinCompressor, "MinCP", line, "" );
extract_value( MaxCompressor, "MaxCP", line, "" ); extract_value( MaxCompressor, "MaxCP", line, "" );
extract_value( MinCompressor, "MinCP_B", line, "" );
extract_value( MaxCompressor, "MaxCP_B", line, "" );
extract_value( CompressorTankValve, "CompressorTankValve", line, "" ); extract_value( CompressorTankValve, "CompressorTankValve", line, "" );
extract_value( CompressorSpeed, "CompressorSpeed", line, "" ); extract_value( CompressorSpeed, "CompressorSpeed", line, "" );
extract_value( EmergencyValveOff, "MinEVP", line, "" ); extract_value( EmergencyValveOff, "MinEVP", line, "" );
@@ -9805,6 +9867,22 @@ void TMoverParameters::LoadFIZ_Brake( std::string const &line ) {
extract_value( extract_value(
ReleaserEnabledOnlyAtNoPowerPos, "ReleaserPowerPosLock", line, ReleaserEnabledOnlyAtNoPowerPos, "ReleaserPowerPosLock", line,
( ( EngineType == TEngineType::DieselEngine ) || ( EngineType == TEngineType::DieselElectric ) ) ? "yes" : "no" ); ( ( EngineType == TEngineType::DieselEngine ) || ( EngineType == TEngineType::DieselElectric ) ) ? "yes" : "no" );
if (MinCompressor_cabB > 0.0) {
MinCompressor_cabA = MinCompressor;
CabDependentCompressor = true;
}
else {
MinCompressor_cabB = MinCompressor;
}
if (MaxCompressor_cabB > 0.0)
{
MaxCompressor_cabA = MaxCompressor;
CabDependentCompressor = true;
}
else {
MaxCompressor_cabB = MaxCompressor;
}
} }
void TMoverParameters::LoadFIZ_Doors( std::string const &line ) { void TMoverParameters::LoadFIZ_Doors( std::string const &line ) {
@@ -10038,6 +10116,7 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
{ {
std::map<std::string, int> brakeopmodes{ std::map<std::string, int> brakeopmodes{
{ "PN", bom_PS + bom_PN }, { "PN", bom_PS + bom_PN },
{ "PNEP", bom_PS + bom_PN + bom_EP },
{ "PNEPMED", bom_PS + bom_PN + bom_EP + bom_MED } { "PNEPMED", bom_PS + bom_PN + bom_EP + bom_MED }
}; };
auto lookup = brakeopmodes.find( extract_value( "BrakeOpModes", line ) ); auto lookup = brakeopmodes.find( extract_value( "BrakeOpModes", line ) );
@@ -10173,6 +10252,9 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
extract_value( StopBrakeDecc, "SBD", line, "" ); extract_value( StopBrakeDecc, "SBD", line, "" );
extract_value( ReleaseParkingBySpringBrake, "ReleaseParkingBySpringBrake", line, "" ); extract_value( ReleaseParkingBySpringBrake, "ReleaseParkingBySpringBrake", line, "" );
extract_value( ReleaseParkingBySpringBrakeWhenDoorIsOpen, "ReleaseParkingBySpringBrakeWhenDoorIsOpen", line, "" );
extract_value( SpringBrakeCutsOffDrive, "SpringBrakeCutsOffDrive", line, "");
extract_value( SpringBrakeDriveEmergencyVel, "SpringBrakeDriveEmergencyVel", line, "");
std::map<std::string, start_t> starts { std::map<std::string, start_t> starts {
{ "Disabled", start_t::disabled }, { "Disabled", start_t::disabled },
@@ -10595,8 +10677,19 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
extract_value( eimc[ eimc_p_abed ], "abed", Input, "" ); extract_value( eimc[ eimc_p_abed ], "abed", Input, "" );
extract_value( eimc[ eimc_p_eped ], "edep", Input, "" ); extract_value( eimc[ eimc_p_eped ], "edep", Input, "" );
extract_value( EIMCLogForce, "eimclf", Input, "" ); extract_value( EIMCLogForce, "eimclf", Input, "" );
extract_value( InvertersNo, "InvNo", Input, "");
extract_value( Flat, "Flat", Input, ""); extract_value( Flat, "Flat", Input, "");
if (eimc[eimc_p_Pmax] > 0 && Power > 0 && InvertersNo == 0) {
InvertersNo = 1;
}
Inverters.resize(InvertersNo);
/*for (int i = 0; i > InvertersNo; i++)
{
inverter x;
Inverters.emplace_back(x);
}*/
break; break;
} }
default: { default: {

View File

@@ -2282,6 +2282,11 @@ double TDriverHandle::GetCP()
return 0; return 0;
} }
double TDriverHandle::GetEP()
{
return 0;
}
double TDriverHandle::GetSound(int i) double TDriverHandle::GetSound(int i)
{ {
return 0; return 0;
@@ -3133,6 +3138,8 @@ double TSt113::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
double ActFlowSpeed; double ActFlowSpeed;
int BCP; int BCP;
CP = PP;
BCP = lround(i_bcp); BCP = lround(i_bcp);
EPS = BEP_K[BCP]; EPS = BEP_K[BCP];
@@ -3168,6 +3175,11 @@ double TSt113::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
} }
double TSt113::GetCP() double TSt113::GetCP()
{
return CP;
}
double TSt113::GetEP()
{ {
return EPS; return EPS;
} }
@@ -3301,6 +3313,8 @@ double TFVel6::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
double dpMainValve; double dpMainValve;
double ActFlowSpeed; double ActFlowSpeed;
CP = PP;
LimPP = Min0R(5 * int(i_bcp < 3.5), HP); LimPP = Min0R(5 * int(i_bcp < 3.5), HP);
if ((i_bcp >= 3.5) && ((i_bcp < 4.3) || (i_bcp > 5.5))) if ((i_bcp >= 3.5) && ((i_bcp < 4.3) || (i_bcp > 5.5)))
ActFlowSpeed = 0; ActFlowSpeed = 0;
@@ -3333,6 +3347,11 @@ double TFVel6::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
} }
double TFVel6::GetCP() double TFVel6::GetCP()
{
return CP;
}
double TFVel6::GetEP()
{ {
return EPS; return EPS;
} }
@@ -3366,6 +3385,8 @@ double TFVE408::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
double dpMainValve; double dpMainValve;
double ActFlowSpeed; double ActFlowSpeed;
CP = PP;
LimPP = Min0R(5 * int(i_bcp < 6.5), HP); LimPP = Min0R(5 * int(i_bcp < 6.5), HP);
if ((i_bcp >= 6.5) && ((i_bcp < 7.5) || (i_bcp > 9.5))) if ((i_bcp >= 6.5) && ((i_bcp < 7.5) || (i_bcp > 9.5)))
ActFlowSpeed = 0; ActFlowSpeed = 0;
@@ -3398,6 +3419,11 @@ double TFVE408::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
} }
double TFVE408::GetCP() double TFVE408::GetCP()
{
return CP;
}
double TFVE408::GetEP()
{ {
return EPS; return EPS;
} }

View File

@@ -541,6 +541,7 @@ class TDriverHandle {
virtual double GetPF(double i_bcp, double PP, double HP, double dt, double ep); virtual double GetPF(double i_bcp, double PP, double HP, double dt, double ep);
virtual void Init(double Press); virtual void Init(double Press);
virtual double GetCP(); virtual double GetCP();
virtual double GetEP();
virtual void SetReductor(double nAdj); //korekcja pozycji reduktora cisnienia virtual void SetReductor(double nAdj); //korekcja pozycji reduktora cisnienia
virtual double GetSound(int i); //pobranie glosnosci wybranego dzwieku virtual double GetSound(int i); //pobranie glosnosci wybranego dzwieku
virtual double GetPos(int i); //pobranie numeru pozycji o zadanym kodzie (funkcji) virtual double GetPos(int i); //pobranie numeru pozycji o zadanym kodzie (funkcji)
@@ -762,10 +763,11 @@ class TSt113 : public TH14K1 {
static double const BPT_K[/*?*/ /*-1..4*/ (4) - (-1) + 1][2]; static double const BPT_K[/*?*/ /*-1..4*/ (4) - (-1) + 1][2];
static double const BEP_K[/*?*/ /*-1..5*/ (5) - (-1) + 1]; static double const BEP_K[/*?*/ /*-1..5*/ (5) - (-1) + 1];
static double const pos_table[11]; // = {-1, 5, -1, 0, 2, 3, 4, 5, 0, 0, 1}; static double const pos_table[11]; // = {-1, 5, -1, 0, 2, 3, 4, 5, 0, 0, 1};
double CP = 0;
public: public:
double GetPF(double i_bcp, double PP, double HP, double dt, double ep)/*override*/; double GetPF(double i_bcp, double PP, double HP, double dt, double ep)/*override*/;
double GetCP()/*override*/; double GetCP()/*override*/;
double GetEP()/*override*/;
double GetPos(int i)/*override*/; double GetPos(int i)/*override*/;
void Init(double Press)/*override*/; void Init(double Press)/*override*/;
@@ -830,10 +832,12 @@ class TFVel6 : public TDriverHandle {
private: private:
double EPS = 0.0; double EPS = 0.0;
static double const pos_table[ 11 ]; // = {-1, 6, -1, 0, 6, 4, 4.7, 5, -1, 0, 1}; static double const pos_table[ 11 ]; // = {-1, 6, -1, 0, 6, 4, 4.7, 5, -1, 0, 1};
double CP = 0.0;
public: public:
double GetPF(double i_bcp, double PP, double HP, double dt, double ep)/*override*/; double GetPF(double i_bcp, double PP, double HP, double dt, double ep)/*override*/;
double GetCP()/*override*/; double GetCP()/*override*/;
double GetEP()/*override*/;
double GetPos(int i)/*override*/; double GetPos(int i)/*override*/;
double GetSound(int i)/*override*/; double GetSound(int i)/*override*/;
void Init(double Press)/*override*/; void Init(double Press)/*override*/;
@@ -848,10 +852,12 @@ class TFVE408 : public TDriverHandle {
private: private:
double EPS = 0.0; double EPS = 0.0;
static double const pos_table[11]; // = {-1, 6, -1, 0, 6, 4, 4.7, 5, -1, 0, 1}; static double const pos_table[11]; // = {-1, 6, -1, 0, 6, 4, 4.7, 5, -1, 0, 1};
double CP = 0.0;
public: public:
double GetPF(double i_bcp, double PP, double HP, double dt, double ep)/*override*/; double GetPF(double i_bcp, double PP, double HP, double dt, double ep)/*override*/;
double GetCP()/*override*/; double GetCP()/*override*/;
double GetEP()/*override*/;
double GetPos(int i)/*override*/; double GetPos(int i)/*override*/;
double GetSound(int i)/*override*/; double GetSound(int i)/*override*/;
void Init(double Press)/*override*/; void Init(double Press)/*override*/;

View File

@@ -453,8 +453,11 @@ TTrain::TTrain() {
bConv[ i ] = false; bConv[ i ] = false;
bComp[ i ][ 0 ] = false; bComp[ i ][ 0 ] = false;
bComp[ i ][ 1 ] = false; bComp[ i ][ 1 ] = false;
//bComp[ i ][ 2 ] = false;
//bComp[ i ][ 3 ] = false;
bHeat[ i ] = false; bHeat[ i ] = false;
} }
bCompressors.clear();
for( int i = 0; i < 9; ++i ) for( int i = 0; i < 9; ++i )
for (int j = 0; j < 10; ++j) for (int j = 0; j < 10; ++j)
{ {
@@ -464,7 +467,7 @@ TTrain::TTrain() {
for ( int i = 0; i < 20; ++i ) for ( int i = 0; i < 20; ++i )
{ {
for ( int j = 0; j < 3; ++j ) for ( int j = 0; j < 4; ++j )
fPress[i][j] = 0.0; fPress[i][j] = 0.0;
bBrakes[i][0] = bBrakes[i][1] = false; bBrakes[i][0] = bBrakes[i][1] = false;
} }
@@ -585,6 +588,8 @@ dictionary_source *TTrain::GetTrainState() {
dict->insert( "main_ctrl_actual_pos", mvControlled->MainCtrlActualPos ); dict->insert( "main_ctrl_actual_pos", mvControlled->MainCtrlActualPos );
dict->insert( "scndctrl_pos", mvControlled->ScndCtrlPos ); dict->insert( "scndctrl_pos", mvControlled->ScndCtrlPos );
dict->insert( "scnd_ctrl_actual_pos", mvControlled->ScndCtrlActualPos ); dict->insert( "scnd_ctrl_actual_pos", mvControlled->ScndCtrlActualPos );
dict->insert( "brakectrl_pos", mvControlled->fBrakeCtrlPos );
dict->insert( "localbrake_pos", mvControlled->LocalBrakePosA );
dict->insert( "new_speed", mvOccupied->NewSpeed); dict->insert( "new_speed", mvOccupied->NewSpeed);
dict->insert( "speedctrl", mvOccupied->SpeedCtrlValue); dict->insert( "speedctrl", mvOccupied->SpeedCtrlValue);
dict->insert( "speedctrlpower", mvOccupied->SpeedCtrlUnit.DesiredPower ); dict->insert( "speedctrlpower", mvOccupied->SpeedCtrlUnit.DesiredPower );
@@ -602,6 +607,7 @@ dictionary_source *TTrain::GetTrainState() {
bPN = ( static_cast<TLSt*>( temp_ham )->GetEDBCP() > 0.2 ); bPN = ( static_cast<TLSt*>( temp_ham )->GetEDBCP() > 0.2 );
} }
dict->insert( "indir_brake", bPN ); dict->insert( "indir_brake", bPN );
dict->insert( "emergency_brake", mvOccupied->AlarmChainFlag );
dict->insert( "brake_delay_flag", mvOccupied->BrakeDelayFlag ); dict->insert( "brake_delay_flag", mvOccupied->BrakeDelayFlag );
dict->insert( "brake_op_mode_flag", mvOccupied->BrakeOpModeFlag ); dict->insert( "brake_op_mode_flag", mvOccupied->BrakeOpModeFlag );
// other controls // other controls
@@ -613,6 +619,7 @@ dictionary_source *TTrain::GetTrainState() {
dict->insert( "radio_channel", RadioChannel() ); dict->insert( "radio_channel", RadioChannel() );
dict->insert( "radio_volume", Global.RadioVolume ); dict->insert( "radio_volume", Global.RadioVolume );
dict->insert( "door_lock", mvOccupied->Doors.lock_enabled ); dict->insert( "door_lock", mvOccupied->Doors.lock_enabled );
dict->insert( "door_step", mvOccupied->Doors.step_enabled );
// movement data // movement data
dict->insert( "velocity", std::abs( mvOccupied->Vel ) ); dict->insert( "velocity", std::abs( mvOccupied->Vel ) );
dict->insert( "tractionforce", std::abs( mvOccupied->Ft ) ); dict->insert( "tractionforce", std::abs( mvOccupied->Ft ) );
@@ -628,7 +635,7 @@ dictionary_source *TTrain::GetTrainState() {
char const *TXTT[ 10 ] = { "fd", "fdt", "fdb", "pd", "pdt", "pdb", "itothv", "1", "2", "3" }; char const *TXTT[ 10 ] = { "fd", "fdt", "fdb", "pd", "pdt", "pdb", "itothv", "1", "2", "3" };
char const *TXTC[ 10 ] = { "fr", "frt", "frb", "pr", "prt", "prb", "im", "vm", "ihv", "uhv" }; char const *TXTC[ 10 ] = { "fr", "frt", "frb", "pr", "prt", "prb", "im", "vm", "ihv", "uhv" };
char const *TXTD[ 10 ] = { "enrot", "nrot", "fill_des", "fill_real", "clutch_des", "clutch_real", "water_temp", "oil_press", "engine_temp", "retarder_fill" }; char const *TXTD[ 10 ] = { "enrot", "nrot", "fill_des", "fill_real", "clutch_des", "clutch_real", "water_temp", "oil_press", "engine_temp", "retarder_fill" };
char const *TXTP[ 3 ] = { "bc", "bp", "sp" }; char const *TXTP[ 4 ] = { "bc", "bp", "sp", "cp" };
char const *TXTB[ 2 ] = { "spring_active", "spring_shutoff" }; char const *TXTB[ 2 ] = { "spring_active", "spring_shutoff" };
for( int j = 0; j < 10; ++j ) for( int j = 0; j < 10; ++j )
dict->insert( ( "eimp_t_" + std::string( TXTT[ j ] ) ), fEIMParams[ 0 ][ j ] ); dict->insert( ( "eimp_t_" + std::string( TXTT[ j ] ) ), fEIMParams[ 0 ][ j ] );
@@ -648,11 +655,39 @@ dictionary_source *TTrain::GetTrainState() {
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_conv" ), bConv[ i ] ); dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_conv" ), bConv[ i ] );
dict->insert( ( "eimp_u" + std::to_string( i + 1 ) + "_comp_a" ), bComp[ i ][ 0 ] ); dict->insert( ( "eimp_u" + std::to_string( i + 1 ) + "_comp_a" ), bComp[ i ][ 0 ] );
dict->insert( ( "eimp_u" + std::to_string( i + 1 ) + "_comp_w" ), bComp[ i ][ 1 ] ); dict->insert( ( "eimp_u" + std::to_string( i + 1 ) + "_comp_w" ), bComp[ i ][ 1 ] );
//dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_comp_a" ), bComp[ i ][ 2 ]);
//dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_comp_w" ), bComp[ i ][ 3 ]);
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_heat" ), bHeat[ i ] ); dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_heat" ), bHeat[ i ] );
}
dict->insert( "compressors_no", (int)bCompressors.size() );
for (int i = 0; i < bCompressors.size(); i++)
{
dict->insert("compressors_" + std::to_string(i + 1) + "_allow", std::get<0>(bCompressors[i]));
dict->insert("compressors_" + std::to_string(i + 1) + "_work", std::get<1>(bCompressors[i]));
dict->insert("compressors_" + std::to_string(i + 1) + "_car_no", std::get<2>(bCompressors[i]));
}
bool kier = (DynamicObject->DirectionGet() * mvOccupied->CabOccupied > 0);
TDynamicObject *p = DynamicObject->GetFirstDynamic(mvOccupied->CabOccupied < 0 ? end::rear : end::front, 4);
int in = 0;
while (p && in < 8)
{
if (p->MoverParameters->eimc[eimc_p_Pmax] > 1)
{
in++;
dict->insert(("eimp_c" + std::to_string(in) + "_invno"), p->MoverParameters->InvertersNo);
for (int j = 0; j < p->MoverParameters->InvertersNo; j++) {
dict->insert(("eimp_c" + std::to_string(in) + "_inv" + std::to_string(j + 1) + "_act"), p->MoverParameters->Inverters[j].IsActive);
dict->insert(("eimp_c" + std::to_string(in) + "_inv" + std::to_string(j + 1) + "_error"), p->MoverParameters->Inverters[j].Error);
dict->insert(("eimp_c" + std::to_string(in) + "_inv" + std::to_string(j + 1) + "_allow"), p->MoverParameters->Inverters[j].Activate);
}
}
p = (kier ? p->Next(4) : p->Prev(4));
} }
for( int i = 0; i < 20; ++i ) { for( int i = 0; i < 20; ++i ) {
for( int j = 0; j < 3; ++j ) { for( int j = 0; j < 4; ++j ) {
dict->insert( ( "eimp_pn" + std::to_string( i + 1 ) + "_" + TXTP[ j ] ), fPress[ i ][ j ] ); dict->insert( ( "eimp_pn" + std::to_string( i + 1 ) + "_" + TXTP[ j ] ), fPress[ i ][ j ] );
} }
for ( int j = 0; j < 2; ++j) { for ( int j = 0; j < 2; ++j) {
@@ -5831,6 +5866,7 @@ void TTrain::OnCommand_radiovolumedecrease(TTrain *Train, command_data const &Co
} }
} }
void TTrain::OnCommand_cabchangeforward( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_cabchangeforward( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
@@ -6149,8 +6185,11 @@ bool TTrain::Update( double const Deltatime )
bConv[i] = false; bConv[i] = false;
bComp[i][0] = false; bComp[i][0] = false;
bComp[i][1] = false; bComp[i][1] = false;
//bComp[i][2] = false;
//bComp[i][3] = false;
bHeat[i] = false; bHeat[i] = false;
} }
bCompressors.clear();
for (int i = 0; i < 20; i++) for (int i = 0; i < 20; i++)
{ {
if (p) if (p)
@@ -6158,6 +6197,7 @@ bool TTrain::Update( double const Deltatime )
fPress[i][0] = p->MoverParameters->BrakePress; fPress[i][0] = p->MoverParameters->BrakePress;
fPress[i][1] = p->MoverParameters->PipePress; fPress[i][1] = p->MoverParameters->PipePress;
fPress[i][2] = p->MoverParameters->ScndPipePress; fPress[i][2] = p->MoverParameters->ScndPipePress;
fPress[i][3] = p->MoverParameters->PantPress;
bBrakes[i][0] = p->MoverParameters->SpringBrake.IsActive; bBrakes[i][0] = p->MoverParameters->SpringBrake.IsActive;
bBrakes[i][1] = p->MoverParameters->SpringBrake.ShuttOff; bBrakes[i][1] = p->MoverParameters->SpringBrake.ShuttOff;
bDoors[i][1] = ( p->MoverParameters->Doors.instances[ side::left ].position > 0.f ); bDoors[i][1] = ( p->MoverParameters->Doors.instances[ side::left ].position > 0.f );
@@ -6178,6 +6218,10 @@ bool TTrain::Update( double const Deltatime )
if (p->MoverParameters->CompressorSpeed > 0.00001) if (p->MoverParameters->CompressorSpeed > 0.00001)
{ {
bComp[iUnitNo - 1][1] = (bComp[iUnitNo - 1][1] || p->MoverParameters->CompressorFlag); bComp[iUnitNo - 1][1] = (bComp[iUnitNo - 1][1] || p->MoverParameters->CompressorFlag);
bCompressors.emplace_back(
p->MoverParameters->CompressorAllow || (p->MoverParameters->CompressorStart == start_t::automatic),
p->MoverParameters->CompressorFlag,
i);
} }
if ((in < 8) && (p->MoverParameters->eimc[eimc_p_Pmax] > 1)) if ((in < 8) && (p->MoverParameters->eimc[eimc_p_Pmax] > 1))
{ {
@@ -6199,6 +6243,8 @@ bool TTrain::Update( double const Deltatime )
bBatt[in] = p->MoverParameters->Battery; bBatt[in] = p->MoverParameters->Battery;
bConv[in] = p->MoverParameters->ConverterFlag; bConv[in] = p->MoverParameters->ConverterFlag;
bHeat[in] = p->MoverParameters->Heating; bHeat[in] = p->MoverParameters->Heating;
//bComp[in][2] = (p->MoverParameters->CompressorAllow || (p->MoverParameters->CompressorStart == start_t::automatic));
//bComp[in][3] = (p->MoverParameters->CompressorFlag);
in++; in++;
iPowerNo = in; iPowerNo = in;
} }
@@ -6236,6 +6282,7 @@ bool TTrain::Update( double const Deltatime )
fPress[i][0] fPress[i][0]
= fPress[i][1] = fPress[i][1]
= fPress[i][2] = fPress[i][2]
= fPress[i][3]
= 0; = 0;
bDoors[i][0] bDoors[i][0]
= bDoors[i][1] = bDoors[i][1]

View File

@@ -780,6 +780,7 @@ private:
bool bBatt[8]; // baterie bool bBatt[8]; // baterie
bool bConv[8]; // przetwornice bool bConv[8]; // przetwornice
bool bComp[8][2]; // sprezarki bool bComp[8][2]; // sprezarki
std::vector<std::tuple<bool, bool, int>> bCompressors;
bool bHeat[8]; // grzanie bool bHeat[8]; // grzanie
// McZapkie: do syczenia // McZapkie: do syczenia
float fPPress, fNPress; float fPPress, fNPress;
@@ -798,7 +799,7 @@ private:
bool m_couplingdisconnect { false }; bool m_couplingdisconnect { false };
public: public:
float fPress[20][3]; // cisnienia dla wszystkich czlonow float fPress[20][4]; // cisnienia dla wszystkich czlonow
bool bBrakes[20][2]; // zalaczenie i dzialanie hamulcow bool bBrakes[20][2]; // zalaczenie i dzialanie hamulcow
static std::vector<std::string> const fPress_labels; static std::vector<std::string> const fPress_labels;
float fEIMParams[9][10]; // parametry dla silnikow asynchronicznych float fEIMParams[9][10]; // parametry dla silnikow asynchronicznych