17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 02:49:19 +02:00

fix: bound MotorParam and MPTRelay indices

This commit is contained in:
jerrrrycho
2026-10-01 19:33:53 +02:00
parent f05b58b0e9
commit 46993b1ad3
2 changed files with 65 additions and 25 deletions

View File

@@ -1086,7 +1086,7 @@ struct TMPTRelay
double Iup = 0.0;
double Idown = 0.0;
};
typedef TMPTRelay TMPTRelayTable[8];
typedef TMPTRelay TMPTRelayTable[MotorParametersArraySize + 1]; // indexed like MotorParam
struct TMotorParameters
{
@@ -1729,6 +1729,11 @@ class TMoverParameters
TMotorParameters MotorParam[MotorParametersArraySize + 1];
/*rozne parametry silnika przy bocznikowaniach*/
/*dla lokomotywy spalinowej z przekladnia mechaniczna: przelozenia biegow*/
// bounds-safe read access to MotorParam
TMotorParameters const &motor_param(int const Position) const
{
return MotorParam[std::clamp(Position, 0, MotorParametersArraySize)];
}
TTransmision Transmision;
// record {liczba zebow przekladni}
// NToothM, NToothW : byte;

View File

@@ -355,7 +355,7 @@ double TMoverParameters::Current(double n, double U)
if (DynamicBrakeFlag && !FuseFlag && DynamicBrakeType == dbrake_automatic && Power110vIsAvailable && Mains) // hamowanie EP09 //TUHEX
{
// TODO: zrobic bardziej uniwersalne nie tylko dla EP09
MotorCurrent = -std::max(MotorParam[0].fi * (Vadd / (Vadd + MotorParam[0].Isat) - MotorParam[0].fi0), 0.) * n * 2.0 / DynamicBrakeRes;
MotorCurrent = -std::max(motor_param(0).fi * (Vadd / (Vadd + motor_param(0).Isat) - motor_param(0).fi0), 0.) * n * 2.0 / DynamicBrakeRes;
}
else if (RList[MainCtrlActualPos].Bn == 0 || false == StLinFlag)
{
@@ -390,7 +390,7 @@ double TMoverParameters::Current(double n, double U)
if (DynamicBrakeType == dbrake_switch && TrainType == dt_ET42)
{ // z Megapacka
Rz = WindingRes + R;
MotorCurrent = -MotorParam[SP].fi * n / Rz; //{hamowanie silnikiem na oporach rozruchowych}
MotorCurrent = -motor_param(SP).fi * n / Rz; //{hamowanie silnikiem na oporach rozruchowych}
}
}
else
@@ -398,13 +398,13 @@ double TMoverParameters::Current(double n, double U)
}
else
{
U1 = U + Mn * n * MotorParam[SP].fi0 * MotorParam[SP].fi;
U1 = U + Mn * n * motor_param(SP).fi0 * motor_param(SP).fi;
// writepaslog("U1 ", FloatToStr(U1));
// writepaslog("Isat ", FloatToStr(MotorParam[SP].Isat));
// writepaslog("fi ", FloatToStr(MotorParam[SP].fi));
Isf = Sign(U1) * MotorParam[SP].Isat;
Isf = Sign(U1) * motor_param(SP).Isat;
// writepaslog("Isf ", FloatToStr(Isf));
Delta = square(Isf * Rz + Mn * MotorParam[SP].fi * n - U1) + 4.0 * U1 * Isf * Rz; // 105 * 1.67 + Mn * 140.9 * 20.532 - U1
Delta = square(Isf * Rz + Mn * motor_param(SP).fi * n - U1) + 4.0 * U1 * Isf * Rz; // 105 * 1.67 + Mn * 140.9 * 20.532 - U1
// DeltaQ = Isf * Rz + Mn * MotorParam[SP].fi * n - U1 + 4 * U1 * Isf * Rz;
// writepaslog("Delta ", FloatToStr(Delta));
// writepaslog("DeltaQ ", FloatToStr(DeltaQ));
@@ -412,9 +412,9 @@ double TMoverParameters::Current(double n, double U)
if (Mains)
{
if (U > 0)
MotorCurrent = (U1 - Isf * Rz - Mn * MotorParam[SP].fi * n + std::sqrt(Delta)) / (2.0 * Rz);
MotorCurrent = (U1 - Isf * Rz - Mn * motor_param(SP).fi * n + std::sqrt(Delta)) / (2.0 * Rz);
else
MotorCurrent = (U1 - Isf * Rz - Mn * MotorParam[SP].fi * n - std::sqrt(Delta)) / (2.0 * Rz);
MotorCurrent = (U1 - Isf * Rz - Mn * motor_param(SP).fi * n - std::sqrt(Delta)) / (2.0 * Rz);
}
else
MotorCurrent = 0;
@@ -5537,9 +5537,9 @@ double TMoverParameters::TractionForce(double dt)
case TEngineType::DieselEngine:
{
if (ShuntMode) // dodatkowa przekładnia np. dla 2Ls150
dtrans = AnPos * Transmision.Ratio * MotorParam[ScndCtrlActualPos].mIsat;
dtrans = AnPos * Transmision.Ratio * motor_param(ScndCtrlActualPos).mIsat;
else
dtrans = Transmision.Ratio * MotorParam[ScndCtrlActualPos].mIsat;
dtrans = Transmision.Ratio * motor_param(ScndCtrlActualPos).mIsat;
dmoment = dizel_Momentum(dizel_fill, dtrans * nrot * DirActive, dt); // oblicza tez enrot
break;
@@ -5984,10 +5984,10 @@ double TMoverParameters::TractionForce(double dt)
Mm = Mw / Transmision.Ratio; // moment silnika trakcyjnego
// with MotorParam[ScndCtrlPos] do
if (abs(Mm) > MotorParam[ScndCtrlPos].fi)
Im = NPoweredAxles * abs(abs(Mm) / MotorParam[ScndCtrlPos].mfi + MotorParam[ScndCtrlPos].mIsat);
if (abs(Mm) > motor_param(ScndCtrlPos).fi)
Im = NPoweredAxles * abs(abs(Mm) / motor_param(ScndCtrlPos).mfi + motor_param(ScndCtrlPos).mIsat);
else
Im = NPoweredAxles * sqrt(abs(Mm * MotorParam[ScndCtrlPos].Isat));
Im = NPoweredAxles * sqrt(abs(Mm * motor_param(ScndCtrlPos).Isat));
if (ShuntMode)
{
@@ -6765,7 +6765,7 @@ double TMoverParameters::Momentum(double I)
SP = RList[MainCtrlActualPos].ScndAct;
// Momentum:=mfi*I*(1-1.0/(Abs(I)/mIsat+1));
return MotorParam[SP].mfi * I * (abs(I) / (abs(I) + MotorParam[SP].mIsat) - MotorParam[SP].mfi0);
return motor_param(SP).mfi * I * (abs(I) / (abs(I) + motor_param(SP).mIsat) - motor_param(SP).mfi0);
}
// *************************************************************************************************
@@ -6776,7 +6776,7 @@ double TMoverParameters::MomentumF(double I, double Iw, int SCP)
{
// umozliwia dokladne sterowanie wzbudzeniem
return MotorParam[SCP].mfi * I * std::max(abs(Iw) / (abs(Iw) + MotorParam[SCP].mIsat) - MotorParam[SCP].mfi0, 0.);
return motor_param(SCP).mfi * I * std::max(abs(Iw) / (abs(Iw) + motor_param(SCP).mIsat) - motor_param(SCP).mfi0, 0.);
}
// *************************************************************************************************
@@ -6909,7 +6909,7 @@ bool TMoverParameters::AutoRelayCheck(void)
}
// sprawdzenie wszystkich warunkow (AutoRelayFlag, AutoSwitch, Im<Imin)
auto const ARFASI2{(false == AutoRelayFlag || (MotorParam[ScndCtrlActualPos].AutoSwitch && abs(Im) < Imin))};
auto const ARFASI2{(false == AutoRelayFlag || (motor_param(ScndCtrlActualPos).AutoSwitch && abs(Im) < Imin))};
auto const ARFASI{
(false == AutoRelayFlag || (RList[MainCtrlActualPos].AutoSwitch && abs(Im) < Imin) || (!RList[MainCtrlActualPos].AutoSwitch && RList[MainCtrlActualPos].Relay < MainCtrlPos))};
// brak PSR na tej pozycji działa PSR i prąd poniżej progu
@@ -7732,13 +7732,13 @@ bool TMoverParameters::dizel_AutoGearCheck(void)
{
auto OK{false};
auto const VelUp{(MotorParam[ScndCtrlActualPos].mfi0 != 0.0 ?
MotorParam[ScndCtrlActualPos].mfi0 + (MotorParam[ScndCtrlActualPos].mfi - MotorParam[ScndCtrlActualPos].mfi0) * std::max(0.0, eimic_real) :
MotorParam[ScndCtrlActualPos].mfi)};
auto const VelUp{(motor_param(ScndCtrlActualPos).mfi0 != 0.0 ?
motor_param(ScndCtrlActualPos).mfi0 + (motor_param(ScndCtrlActualPos).mfi - motor_param(ScndCtrlActualPos).mfi0) * std::max(0.0, eimic_real) :
motor_param(ScndCtrlActualPos).mfi)};
auto const VelDown{(MotorParam[ScndCtrlActualPos].fi0 != 0.0 && eimic_real <= 0.0 ? MotorParam[ScndCtrlActualPos].fi0 : MotorParam[ScndCtrlActualPos].fi)};
auto const VelDown{(motor_param(ScndCtrlActualPos).fi0 != 0.0 && eimic_real <= 0.0 ? motor_param(ScndCtrlActualPos).fi0 : motor_param(ScndCtrlActualPos).fi)};
if (MotorParam[ScndCtrlActualPos].AutoSwitch && Mains)
if (motor_param(ScndCtrlActualPos).AutoSwitch && Mains)
{
if (RList[MainCtrlPos].Mn == 0 && !hydro_TC)
{
@@ -7749,7 +7749,7 @@ bool TMoverParameters::dizel_AutoGearCheck(void)
}
else
{
if (MotorParam[ScndCtrlActualPos].AutoSwitch && dizel_automaticgearstatus == 0) // sprawdz czy zmienic biegi
if (motor_param(ScndCtrlActualPos).AutoSwitch && dizel_automaticgearstatus == 0) // sprawdz czy zmienic biegi
{
if (Vel > VelUp)
{
@@ -7834,7 +7834,7 @@ bool TMoverParameters::dizel_AutoGearCheck(void)
}
else
dizel_EngageSwitch(0.0);
if (!(MotorParam[ScndCtrlActualPos].mIsat > 0))
if (!(motor_param(ScndCtrlActualPos).mIsat > 0))
dizel_EngageSwitch(0.0); // wylacz sprzeglo na pozycjach neutralnych
if (!AutoRelayFlag)
ScndCtrlActualPos = ScndCtrlPos;
@@ -7956,7 +7956,7 @@ double TMoverParameters::dizel_fillcheck(int mcp, double dt)
// napelnienie zalezne od MainCtrlPos
if (EIMCtrlType > 0)
{
realfill = std::max(0.0, std::min(eimic_real, 1 - MotorParam[ScndCtrlActualPos].Isat));
realfill = std::max(0.0, std::min(eimic_real, 1 - motor_param(ScndCtrlActualPos).Isat));
if (eimic_real > 0.005 && !hydro_TC_Lockup)
{
dizel_nreg_min = std::min(dizel_nreg_min + 2.5 * dt, dizel_nmin_hdrive + eimic_real * dizel_nmin_hdrive_factor);
@@ -8044,7 +8044,7 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
double Moment = 0, enMoment = 0, gearMoment = 0, eps = 0, newn = 0, friction = 0, neps = 0;
double TorqueH = 0, TorqueL = 0, TorqueC = 0;
n = n * CabActive;
if (MotorParam[ScndCtrlActualPos].mIsat < 0.001 || DirActive == 0)
if (motor_param(ScndCtrlActualPos).mIsat < 0.001 || DirActive == 0)
n = enrot;
friction = dizel_engagefriction;
hydro_TC_nIn = enrot; // wal wejsciowy przetwornika momentu
@@ -9079,6 +9079,17 @@ int s2NNW(std::string s)
// Q: 20160717
// *************************************************************************************************
// parsowanie Motor Param Table
// checks a motor parameter table position read from the .fiz file against the table size
static bool is_valid_mpt_index(int const Index)
{
if (Index >= 0 && Index <= MotorParametersArraySize)
{
return true;
}
WriteLog("Read MPT: position " + std::to_string(Index) + " out of range 0-" + std::to_string(MotorParametersArraySize) + " in line " + std::to_string(LISTLINE));
return false;
}
bool TMoverParameters::readMPT0(std::string const &line)
{
@@ -9091,6 +9102,10 @@ bool TMoverParameters::readMPT0(std::string const &line)
}
int idx = 0; // numer pozycji
parser >> idx;
if (false == is_valid_mpt_index(idx))
{
return false;
}
switch (EngineType)
{
case TEngineType::DieselEngine:
@@ -9155,6 +9170,10 @@ bool TMoverParameters::readMPTElectricSeries(std::string const &line)
}
int idx = 0; // numer pozycji
parser >> idx;
if (false == is_valid_mpt_index(idx))
{
return false;
}
parser >> MotorParam[idx].mfi >> MotorParam[idx].mIsat >> MotorParam[idx].fi >> MotorParam[idx].Isat;
if (true == parser.getTokens(1, false))
{
@@ -9180,6 +9199,10 @@ bool TMoverParameters::readMPTDieselElectric(std::string const &line)
}
int idx = 0; // numer pozycji
parser >> idx;
if (false == is_valid_mpt_index(idx))
{
return false;
}
parser >> MotorParam[idx].mfi >> MotorParam[idx].mIsat >> MotorParam[idx].fi >> MotorParam[idx].Isat >> MPTRelay[idx].Iup >> MPTRelay[idx].Idown;
return true;
@@ -9196,6 +9219,10 @@ bool TMoverParameters::readMPTDieselEngine(std::string const &line)
}
int idx = 0; // numer pozycji
parser >> idx;
if (false == is_valid_mpt_index(idx))
{
return false;
}
parser >> MotorParam[idx].mIsat >> MotorParam[idx].fi >> MotorParam[idx].mfi;
if (true == parser.getTokens(1, false))
{
@@ -11740,6 +11767,14 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
CompressorPower = 3;
}
// for these engine types secondary controller positions index MotorParam table
if ((EngineType == TEngineType::ElectricSeriesMotor || EngineType == TEngineType::DieselEngine || EngineType == TEngineType::DieselElectric) &&
ScndCtrlPosNo > MotorParametersArraySize)
{
WriteLog("SCPN=" + std::to_string(ScndCtrlPosNo) + " exceeds motor parameter table size, limited to " + std::to_string(MotorParametersArraySize));
ScndCtrlPosNo = MotorParametersArraySize;
}
// WriteLog("aa = " + AxleArangement + " " + std::string( Pos("o", AxleArangement)) );
if (contains(AxleArangement, "o") && EngineType == TEngineType::ElectricSeriesMotor)