16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 09:19:18 +02:00

EIM vehicle can have multiple inverters

This commit is contained in:
Królik Uszasty
2020-10-31 19:58:25 +01:00
parent 59cd762cb1
commit 3b32473fff
4 changed files with 68 additions and 6 deletions

View File

@@ -3129,6 +3129,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 :

View File

@@ -769,6 +769,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:
@@ -1269,6 +1279,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

@@ -5916,6 +5916,12 @@ double TMoverParameters::TractionForce( double dt ) {
case TEngineType::ElectricInductionMotor: case TEngineType::ElectricInductionMotor:
{ {
if( true == Mains ) { if( true == Mains ) {
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)
{ {
@@ -6011,7 +6017,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;
@@ -6057,6 +6063,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)*/) *
@@ -6107,6 +6118,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
@@ -6123,7 +6136,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
@@ -6137,8 +6154,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];
@@ -6179,11 +6196,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;
@@ -10591,8 +10612,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

@@ -647,8 +647,24 @@ dictionary_source *TTrain::GetTrainState() {
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 ) + "_heat" ), bHeat[ i ] ); dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_heat" ), bHeat[ 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++;
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->NextC(4) : p->PrevC(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 < 3; ++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 ] );