/* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "stdafx.h" #include "McZapkie/MOVER.h" // VGRAPH_SHADOW_CHECK: the code of TMoverParameters extracted to the functions shared with the vehicle graph, in its // original form, working on copies of the state. Mover runs it next to every call of the extracted functions and logs // the differences, so the extraction can be verified on real vehicles. remove once the reference set of vehicles // shows no differences #ifdef VGRAPH_SHADOW_CHECK #include "utilities/Logs.h" #include "utilities/utilities.h" namespace { // as in Mover.cpp inline double square(double val) { return val * val; } } // namespace void TMoverParameters::shadow_compare(char const *What, double const Original, double const Extracted) const { if (Original == Extracted || (std::isnan(Original) && std::isnan(Extracted))) { return; } WriteLog("VGRAPH_SHADOW_CHECK: " + Name + ": " + What + " differs: original " + std::to_string(Original) + ", extracted " + std::to_string(Extracted)); } double TMoverParameters::shadow_series_motor_current(double const U, double const n, double const Mn, double const Rz, int const SP) const { double MotorCurrent; double U1 = U + Mn * n * motor_param(SP).fi0 * motor_param(SP).fi; double Isf = Sign(U1) * motor_param(SP).Isat; double Delta = square(Isf * Rz + Mn * motor_param(SP).fi * n - U1) + 4.0 * U1 * Isf * Rz; if (U > 0) MotorCurrent = (U1 - Isf * Rz - Mn * motor_param(SP).fi * n + std::sqrt(Delta)) / (2.0 * Rz); else MotorCurrent = (U1 - Isf * Rz - Mn * motor_param(SP).fi * n - std::sqrt(Delta)) / (2.0 * Rz); return MotorCurrent; } double TMoverParameters::shadow_brake_rigging_shoe_force(double K, double &Ntotal) const { double u = (BrakePress * P2FTrans - BrakeCylSpring) * BrakeCylMult[0] - BrakeSlckAdj; if (u * BrakeRigEff > Ntotal) // histereza na nacisku klockow Ntotal = u * BrakeRigEff; else { u = (BrakePress * P2FTrans - BrakeCylSpring) * BrakeCylMult[0] - BrakeSlckAdj; if (u * (2.0 - BrakeRigEff) < Ntotal) // histereza na nacisku klockow Ntotal = u * (2.0 - BrakeRigEff); } auto const NBrakeAxles{NAxles}; if (NBrakeAxles * NBpA > 0) { if (Ntotal > 0) // nie luz K += Ntotal; // w kN K *= static_cast(BrakeCylNo) / (NBrakeAxles * static_cast(NBpA)); // w kN na os } return K; } void TMoverParameters::shadow_induction_motor(double const PosRatio, double tmp, double const dt, double *Eimv, double &Eimvpr, double &Vaddcopy, induction_motor_outputs &Output) const { Eimvpr += std::max(std::min(PosRatio - Eimvpr, 0.02), -0.02) * 12 * tmp /*2{+4*byte(PosRatio= 0) Vaddcopy *= 1.0 - 2.0 * dt; else if (std::abs(EngineVoltage) < EnginePowerSource.CollectorParameters.MaxV) Vaddcopy *= 1.0 - dt; else Vaddcopy = std::max(Vaddcopy * (1.0 - 0.2 * dt), 0.007 * (std::abs(EngineVoltage) - (EnginePowerSource.CollectorParameters.MaxV - 100))); Output.Itot = Eimv[eimv_Ipoj] * (0.01 + std::min(0.99, 0.99 - Vaddcopy)); Output.EnginePower = abs(Eimv[eimv_Ic] * Eimv[eimv_U] * NPoweredAxles) / 1000; Output.Mm = Eimv[eimv_M] * DirAbsolute; Output.Mw = Output.Mm * Transmision.Ratio * Transmision.Efficiency; Output.Fw = Output.Mw * 2.0 / WheelDiameter; Output.Ft = Output.Fw * NPoweredAxles * InvertersRatio; Eimv[eimv_Fr] = DirAbsolute * Output.Ft / 1000; } #endif