mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-12 14:01:02 +01:00
Merge branch 'master' into feat/renderers-cleanup
This commit is contained in:
@@ -678,6 +678,13 @@ struct TTractionParam
|
||||
};
|
||||
/*powyzsze parametry zwiazane sa z torem po ktorym aktualnie pojazd jedzie*/
|
||||
|
||||
// what a horn needs to sound: air from the main reservoir, or the low voltage
|
||||
enum class horn_supply
|
||||
{
|
||||
air,
|
||||
electric
|
||||
};
|
||||
|
||||
/// <summary>High-level brake-system family.</summary>
|
||||
enum class TBrakeSystem
|
||||
{
|
||||
@@ -1712,6 +1719,10 @@ class TMoverParameters
|
||||
float DistanceCounterDoublePressPeriod = {1.f}; // czas w jakim nalezy podwojnie wcisnac przycisk, aby rozpoczac pomiar odleglosci
|
||||
TSecuritySystem SecuritySystem;
|
||||
int EmergencyBrakeWarningSignal{0}; // combined with basic WarningSignal when manual emergency brake is active
|
||||
horn_supply HornSupply{horn_supply::air}; // of the low and high tone horns (WarningSignal 1 and 2)
|
||||
horn_supply Horn3Supply{horn_supply::air}; // of the third horn (WarningSignal 4)
|
||||
// main reservoir pressure [bar, as MinCP and MaxCP] below which a pneumatic horn stays silent
|
||||
static constexpr double HornMinPressure{2.0};
|
||||
TUniversalCtrlTable UniCtrlList; /*lista pozycji uniwersalnego nastawnika*/
|
||||
int UniCtrlListSize = 0; /*wielkosc listy pozycji uniwersalnego nastawnika*/
|
||||
bool UniCtrlIntegratedBrakePNCtrl = false; /*zintegrowany nastawnik JH obsluguje hamulec PN*/
|
||||
@@ -2003,6 +2014,8 @@ class TMoverParameters
|
||||
bool CompressorAllow = false; /*! zezwolenie na uruchomienie sprezarki NBMX*/
|
||||
bool CompressorAllowLocal{true}; // local device state override (most units don't have this fitted so it's set to true not to intefere)
|
||||
bool CompressorGovernorLock{false}; // indicates whether compressor pressure switch was activated due to reaching cut-out pressure
|
||||
double CompressorStartDelay{0.0}; // time [s] the compressor waits after getting its power before it can start, after the engine starts say
|
||||
double CompressorPowerTime{0.0}; // time [s] since the compressor got its power
|
||||
bool CompressorTankValve{false}; // indicates excessive pressure is vented from compressor tank directly and instantly
|
||||
start_t CompressorStart{start_t::manual}; // whether the compressor is started manually, or another way
|
||||
start_t PantographCompressorStart{start_t::manual};
|
||||
@@ -2230,6 +2243,7 @@ class TMoverParameters
|
||||
// TODO: move these switch types where they belong, cabin definition
|
||||
std::string PantSwitchType;
|
||||
std::string ConvSwitchType;
|
||||
bool HeatingSwitchImpulse{false}; // the train heating switch springs back to its middle position
|
||||
std::string StLinSwitchType;
|
||||
|
||||
bool Heating = false; // ogrzewanie 'Winger 020304
|
||||
@@ -2441,11 +2455,47 @@ class TMoverParameters
|
||||
double Adhesive(double staticfriction) const;
|
||||
double TractionForce(double dt);
|
||||
double FrictionForce() const;
|
||||
double BrakeForceR(double ratio, double velocity);
|
||||
double BrakeForceR(double ratio, double velocity) const;
|
||||
double BrakeForceP(double press, double velocity) const;
|
||||
double BrakeForce(const TTrackParam &Track);
|
||||
double CouplerForce(int const End, double dt);
|
||||
void CollisionDetect(int const End, double const dt);
|
||||
// closing speed of a collision [km/h] above which the vehicles involved may derail, adjusted for their mass ratio
|
||||
static constexpr double SafeCollisionVelocity{15.0};
|
||||
// closing speed [km/h] of the End of this vehicle and the OtherEnd of the other vehicle it touches, along the coupler
|
||||
// axis: the sum of the speeds in a head-on collision, the difference in a rear-end one, negative when they part
|
||||
double CollisionVelocity(int const End, TMoverParameters const &Other, int const OtherEnd) const;
|
||||
// velocity [m/s] of this vehicle relative to the other vehicle it touches with its End and the OtherEnd of the
|
||||
// other one, along this vehicle's axis
|
||||
double CouplerVelocityDifference(int const End, TMoverParameters const &Other, int const OtherEnd) const;
|
||||
// whether the automatic couplers at the End of this vehicle and the OtherEnd of the other one can catch each other on
|
||||
// contact, rather than the vehicles colliding (with crash damage enabled, only at a closing speed which doesn't derail them)
|
||||
bool AutomaticCouplingSafe(int const End, TMoverParameters const &Other, int const OtherEnd) const;
|
||||
// the horns of the Signal (WarningSignal bits) which have the air or the voltage they need to sound
|
||||
int SoundingHorns(int const Signal) const;
|
||||
// whether the signal lamps of the main circuit (line contactors, ground relay, motor overload relays) can light:
|
||||
// the pressure switch, when fitted, cuts the start off and puts them out, otherwise they go out once the brakes are applied
|
||||
bool MainCircuitLampsEnabled() const
|
||||
{
|
||||
return false == ControlPressureSwitch && (HasControlPressureSwitch || BrakePress < 1.0);
|
||||
}
|
||||
// whether the lamp of the open line contactors is lit, telling the start can be made
|
||||
bool LineContactorsLampLit() const
|
||||
{
|
||||
return false == StLinFlag && MainCircuitLampsEnabled();
|
||||
}
|
||||
// whether the pumps a joint oil and fuel pump switch works, those not started automatically, are all switched on
|
||||
bool OilFuelPumpsEnabled() const
|
||||
{
|
||||
auto const fuelmanual{FuelPump.start_type != start_t::automatic};
|
||||
auto const oilmanual{OilPump.start_type != start_t::automatic};
|
||||
return (fuelmanual || oilmanual) && (false == fuelmanual || FuelPump.is_enabled) && (false == oilmanual || OilPump.is_enabled);
|
||||
}
|
||||
// whether the radio is switched on and has the low voltage to work
|
||||
bool RadioPowered() const
|
||||
{
|
||||
return Radio && (Power24vIsAvailable || Power110vIsAvailable);
|
||||
}
|
||||
/*obrot kol uwzgledniajacy poslizg*/
|
||||
double ComputeRotatingWheel(double WForce, double dt, double n) const;
|
||||
|
||||
|
||||
@@ -17,6 +17,9 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "utilities/Timer.h"
|
||||
#include "utilities/parser.h"
|
||||
#include "simulation/simulation.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <format>
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Ra: tu należy przenosić funcje z mover.pas, które nie są z niego wywoływane.
|
||||
@@ -50,8 +53,13 @@ double ComputeCollision(double &v1, double &v2, double m1, double m2, double bet
|
||||
double sum = m1 + m2;
|
||||
double w1 = (m2 * v2 * 2.0 + v1 * (m1 - m2)) / sum;
|
||||
double w2 = (m1 * v1 * 2.0 + v2 * (m2 - m1)) / sum;
|
||||
v1 = w1 * std::sqrt(1.0 - beta); // niejawna zmiana predkosci wskutek zderzenia
|
||||
v2 = w2 * std::sqrt(1.0 - beta);
|
||||
// the collision changes the velocities directly: the bounce loses energy in the velocities relative to the
|
||||
// centre of mass only, the pair keeps its momentum. scaling the velocities themselves braked the vehicles
|
||||
// down with every step their couplers spent stretched or pressed in all the way (eu07/maszyna#553)
|
||||
auto const centre{(m1 * v1 + m2 * v2) / sum};
|
||||
auto const restitution{std::sqrt(1.0 - beta)};
|
||||
v1 = std::lerp(centre, w1, restitution);
|
||||
v2 = std::lerp(centre, w2, restitution);
|
||||
return m1 * (w2 - w1) * (1 - beta);
|
||||
}
|
||||
}
|
||||
@@ -1177,6 +1185,56 @@ double TMoverParameters::EngineMaxRPM() const
|
||||
std::numeric_limits<double>::max(); // shouldn't ever get here but, eh
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
// prędkość zbliżania się stykających się końców pojazdów przy zderzeniu, w km/h
|
||||
// *************************************************************************************************
|
||||
double TMoverParameters::CollisionVelocity(int const End, TMoverParameters const &Other, int const OtherEnd) const
|
||||
{
|
||||
auto const velocitydifference{CouplerVelocityDifference(End, Other, OtherEnd)};
|
||||
// the front end closes in on the other vehicle when this one moves forward faster, the rear end when it's slower
|
||||
return (End == end::front ? velocitydifference : -velocitydifference) * 3.6; // m/s -> km/h
|
||||
}
|
||||
|
||||
double TMoverParameters::CouplerVelocityDifference(int const End, TMoverParameters const &Other, int const OtherEnd) const
|
||||
{
|
||||
// V runs along the vehicle's own axis, towards its front; the other vehicle's velocity is turned around when the
|
||||
// vehicles face each other (touch with the same ends)
|
||||
return V - Other.V * DirPatch(End, OtherEnd);
|
||||
}
|
||||
|
||||
bool TMoverParameters::AutomaticCouplingSafe(int const End, TMoverParameters const &Other, int const OtherEnd) const
|
||||
{
|
||||
return false == Global.crash_damage || CollisionVelocity(End, Other, OtherEnd) <= SafeCollisionVelocity;
|
||||
}
|
||||
|
||||
int TMoverParameters::SoundingHorns(int const Signal) const
|
||||
{
|
||||
auto const supplied{[this](horn_supply const Supply) {
|
||||
if (Supply == horn_supply::electric)
|
||||
{
|
||||
return Power24vIsAvailable || Power110vIsAvailable;
|
||||
}
|
||||
if (VeselVolume > 0.0)
|
||||
{
|
||||
return Compressor >= HornMinPressure;
|
||||
}
|
||||
// a vehicle without a main reservoir of its own takes the air from the main pipe, a vehicle without either
|
||||
// (a road vehicle, say) has no air to check
|
||||
auto const mainpipe{((Couplers[end::front].AllowedFlag | Couplers[end::rear].AllowedFlag) & coupling::mainhose) != 0};
|
||||
return false == mainpipe || ScndPipePress >= HornMinPressure;
|
||||
}};
|
||||
auto horns{0};
|
||||
if (supplied(HornSupply))
|
||||
{
|
||||
horns |= Signal & (1 | 2);
|
||||
}
|
||||
if (supplied(Horn3Supply))
|
||||
{
|
||||
horns |= Signal & 4;
|
||||
}
|
||||
return horns;
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
// Q: 20160716
|
||||
// Wykrywanie kolizji
|
||||
@@ -1193,8 +1251,11 @@ void TMoverParameters::CollisionDetect(int const End, double const dt)
|
||||
auto const otherend{Neighbours[End].vehicle_end};
|
||||
auto const &othercoupler{othervehicle->Couplers[otherend]};
|
||||
|
||||
// the velocities along this vehicle's axis: the other vehicle's one is turned around when the vehicles face each
|
||||
// other (touch with the same ends), as in CouplerForce()
|
||||
auto const otherdirection{DirPatch(End, otherend)};
|
||||
auto velocity{V};
|
||||
auto othervehiclevelocity{othervehicle->V};
|
||||
auto othervehiclevelocity{othervehicle->V * otherdirection};
|
||||
// calculate collision force and new velocities for involved vehicles
|
||||
auto const VirtualCoupling{(thiscoupler.CouplingFlag == coupling::faux)};
|
||||
auto CCF{0.0};
|
||||
@@ -1225,28 +1286,25 @@ void TMoverParameters::CollisionDetect(int const End, double const dt)
|
||||
damage_coupler(End);
|
||||
}
|
||||
|
||||
if (thiscoupler.CouplingFlag == coupling::faux || true == TestFlag(othervehicle->DamageFlag, dtrain_out))
|
||||
{ // HACK: limit excessive speed derailment checks to vehicles which aren't part of the same consist
|
||||
auto const safevelocitylimit{15.0};
|
||||
auto const velocitydifference{glm::length(glm::angleAxis(Rot.Rz, glm::dvec3{0, 1, 0}) * V - glm::angleAxis(othervehicle->Rot.Rz, glm::dvec3{0, 1, 0}) * othervehicle->V) *
|
||||
3.6}; // m/s -> km/h
|
||||
// HACK: limit excessive speed derailment checks to vehicles which aren't part of the same consist
|
||||
auto const outsideconsist{thiscoupler.CouplingFlag == coupling::faux || true == TestFlag(othervehicle->DamageFlag, dtrain_out)};
|
||||
auto const velocitydifference{outsideconsist ? CollisionVelocity(End, *othervehicle, otherend) : 0.0};
|
||||
|
||||
if (velocitydifference > safevelocitylimit)
|
||||
if (velocitydifference > SafeCollisionVelocity)
|
||||
{
|
||||
// HACK: crude estimation for potential derail, will take place with velocity difference > 15 km/h adjusted for vehicle mass ratio
|
||||
if (false == TestFlag(DamageFlag, dtrain_out) || false == TestFlag(othervehicle->DamageFlag, dtrain_out))
|
||||
{
|
||||
// HACK: crude estimation for potential derail, will take place with velocity difference > 15 km/h adjusted for vehicle mass ratio
|
||||
if (false == TestFlag(DamageFlag, dtrain_out) || false == TestFlag(othervehicle->DamageFlag, dtrain_out))
|
||||
{
|
||||
WriteLog("Bad driving: " + Name + " and " + othervehicle->Name + " collided with velocity " + to_string(velocitydifference, 0) + " km/h");
|
||||
}
|
||||
WriteLog("Bad driving: " + Name + " and " + othervehicle->Name + " collided with velocity " + to_string(velocitydifference, 0) + " km/h");
|
||||
}
|
||||
|
||||
if (velocitydifference > safevelocitylimit * (TotalMass / othervehicle->TotalMass))
|
||||
{
|
||||
Derail(COLLISION);
|
||||
}
|
||||
if (velocitydifference > safevelocitylimit * (othervehicle->TotalMass / TotalMass))
|
||||
{
|
||||
othervehicle->Derail(COLLISION);
|
||||
}
|
||||
if (velocitydifference > SafeCollisionVelocity * (TotalMass / othervehicle->TotalMass))
|
||||
{
|
||||
Derail(COLLISION);
|
||||
}
|
||||
if (velocitydifference > SafeCollisionVelocity * (othervehicle->TotalMass / TotalMass))
|
||||
{
|
||||
othervehicle->Derail(COLLISION);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1255,21 +1313,15 @@ void TMoverParameters::CollisionDetect(int const End, double const dt)
|
||||
if (false == TestFlag(DamageFlag, dtrain_out))
|
||||
{
|
||||
auto const accelerationchange{(velocity - V) / dt};
|
||||
// if( accelerationchange / AccS < 1.0 ) {
|
||||
// HACK: prevent excessive vehicle pinball cases
|
||||
AccS += accelerationchange;
|
||||
// AccS = std::clamp( AccS, -2.0, 2.0 );
|
||||
V = velocity;
|
||||
// }
|
||||
}
|
||||
if (false == TestFlag(othervehicle->DamageFlag, dtrain_out))
|
||||
{
|
||||
auto const othervehicleaccelerationchange{(othervehiclevelocity - othervehicle->V) / dt};
|
||||
// if( othervehicleaccelerationchange / othervehicle->AccS < 1.0 ) {
|
||||
// HACK: prevent excessive vehicle pinball cases
|
||||
auto const othervehiclenewvelocity{othervehiclevelocity * otherdirection}; // back along the other vehicle's axis
|
||||
auto const othervehicleaccelerationchange{(othervehiclenewvelocity - othervehicle->V) / dt};
|
||||
othervehicle->AccS += othervehicleaccelerationchange;
|
||||
othervehicle->V = othervehiclevelocity;
|
||||
// }
|
||||
othervehicle->V = othervehiclenewvelocity;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4336,7 +4388,10 @@ void TMoverParameters::CompressorCheck(double dt)
|
||||
}
|
||||
}
|
||||
|
||||
auto const compressorpower{(CompressorPower == 0 ? Mains : CompressorPower == 3 ? Mains : Power110vIsAvailable)};
|
||||
// the main circuit, also for a compressor driven by the engine, otherwise the low voltage
|
||||
auto const compressorpower{CompressorPower == 0 || CompressorPower == 3 ? Mains : Power110vIsAvailable};
|
||||
CompressorPowerTime = compressorpower ? CompressorPowerTime + dt : 0.0;
|
||||
auto const compressorready{compressorpower && CompressorPowerTime >= CompressorStartDelay};
|
||||
// TBD: split CompressorAllow into separate enable/disable flags, inherit compressor from basic_device
|
||||
auto const compressorenable{CompressorAllowLocal && (CompressorStart == start_t::automatic || CompressorAllow)};
|
||||
auto const compressordisable{false == compressorenable};
|
||||
@@ -4358,7 +4413,7 @@ void TMoverParameters::CompressorCheck(double dt)
|
||||
|
||||
auto const compressorflag{CompressorFlag};
|
||||
CompressorFlag =
|
||||
compressorpower && false == compressordisable && (false == governorlock || CompressorPower == 3) && (CompressorFlag || (compressorenable && LastSwitchingTime > CtrlDelay));
|
||||
compressorready && false == compressordisable && (false == governorlock || CompressorPower == 3) && (CompressorFlag || (compressorenable && LastSwitchingTime > CtrlDelay));
|
||||
|
||||
if (CompressorFlag && CompressorFlag != compressorflag)
|
||||
{
|
||||
@@ -4392,30 +4447,23 @@ void TMoverParameters::CompressorCheck(double dt)
|
||||
{
|
||||
// vent some air out if there's no governor lock to stop the compressor from exceeding acceptable pressure level
|
||||
SetFlag(SoundFlag, sound::relay | sound::loud);
|
||||
CompressedVolume *= false == governorlockispresent ? 0.80 : // arbitrary amount
|
||||
CompressorTankValve ? MinCompressorF / MaxCompressorF : // drop to mincompressor level
|
||||
0.999; // HACK: drop a tiny bit so the sound doesn't trigger repeatedly
|
||||
auto ventedfraction{0.999}; // HACK: drop a tiny bit so the sound doesn't trigger repeatedly
|
||||
if (false == governorlockispresent)
|
||||
{
|
||||
ventedfraction = 0.80; // arbitrary amount
|
||||
}
|
||||
else if (CompressorTankValve)
|
||||
{
|
||||
ventedfraction = MinCompressorF / MaxCompressorF; // drop to mincompressor level
|
||||
}
|
||||
CompressedVolume *= ventedfraction;
|
||||
if (false == governorlockispresent || CompressorTankValve)
|
||||
{
|
||||
CompressorGovernorLock = false;
|
||||
}
|
||||
}
|
||||
|
||||
// tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę
|
||||
// TODO: draw power from proper high- or low voltage circuit
|
||||
if (CompressorPower == 3)
|
||||
{
|
||||
// diesel-powered compressor doesn't draw power
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: drain power from 110v circuit
|
||||
/*
|
||||
if( compressorowner != nullptr ) {
|
||||
compressorowner->TotalCurrent += 0.0015 * compressorowner->PantographVoltage;
|
||||
}
|
||||
*/
|
||||
}
|
||||
// a compressor not driven by the engine doesn't draw power (some 5 A) from the high- or low voltage circuit yet
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
@@ -5033,7 +5081,7 @@ void TMoverParameters::ComputeTotalForce(double dt)
|
||||
}
|
||||
else
|
||||
{
|
||||
EngineVoltage *= DirAbsolute; // DirActive*CabActive;
|
||||
EngineVoltage *= DirAbsolute; // the reverser of the active cab, relative to the couplers
|
||||
}
|
||||
} // bo nie dzialalo
|
||||
else
|
||||
@@ -5057,6 +5105,14 @@ void TMoverParameters::ComputeTotalForce(double dt)
|
||||
{
|
||||
SlippingWheels = true;
|
||||
}
|
||||
if (true == SlippingWheels && Vel < 0.1 // the same crude trap: (nearly) stopped vehicle...
|
||||
&& std::abs(nrot * M_PI * WheelDiameter - V) < 0.1 / 3.6) // ...with wheels turning at its speed, i.e. locked wheels at the end of a skid
|
||||
{
|
||||
// locked wheels never pass the rotation speed test below once the vehicle stops, and a skidding vehicle
|
||||
// keeps its braking force capped by the sliding adhesion, so the rest of the consist could push it around
|
||||
SlippingWheels = false;
|
||||
nrot = V / M_PI / WheelDiameter;
|
||||
}
|
||||
double temp_nrot = nrot;
|
||||
if (true == SlippingWheels)
|
||||
{
|
||||
@@ -5113,7 +5169,7 @@ void TMoverParameters::ComputeTotalForce(double dt)
|
||||
FTotal = FTrain - Sign(V) * FStand;
|
||||
}
|
||||
|
||||
double TMoverParameters::BrakeForceR(double ratio, double velocity)
|
||||
double TMoverParameters::BrakeForceR(double ratio, double velocity) const
|
||||
{
|
||||
double press = 0;
|
||||
if (MBPM > 2)
|
||||
@@ -5311,7 +5367,7 @@ double TMoverParameters::CouplerForce(int const End, double dt)
|
||||
|
||||
auto const newdistance{initialdistance + 10.0 * distancedelta};
|
||||
|
||||
auto const dV{V - othervehicle->V * DirPatch(End, otherend)};
|
||||
auto const dV{CouplerVelocityDifference(End, *othervehicle, otherend)};
|
||||
auto const absdV{std::abs(dV)};
|
||||
|
||||
// potentially generate sounds on clash or stretch
|
||||
@@ -5424,25 +5480,23 @@ double TMoverParameters::CouplerForce(int const End, double dt)
|
||||
couplingtype &= ~coupling::control;
|
||||
}
|
||||
|
||||
if (Attach(End, otherend, othervehicle, couplingtype))
|
||||
{
|
||||
// HACK: we're reusing sound enum to mark whether vehicle was connected to another
|
||||
SetFlag(AIFlag, sound::attachcoupler);
|
||||
thiscoupler.AutomaticCouplingAllowed = false;
|
||||
othercoupler.AutomaticCouplingAllowed = false;
|
||||
}
|
||||
/*
|
||||
coupler.CouplingFlag = ( coupler.AutomaticCouplingFlag & othercoupler.AutomaticCouplingFlag );
|
||||
SetFlag( coupler.sounds, sound::attachcoupler );
|
||||
*/
|
||||
// too fast for the couplers to catch, the vehicles collide instead (and may derail, see CollisionDetect())
|
||||
auto const safe{AutomaticCouplingSafe(End, *othervehicle, otherend)};
|
||||
auto const caught{safe && Attach(End, otherend, othervehicle, couplingtype)};
|
||||
// HACK: we're reusing sound enum to mark whether vehicle was connected to another
|
||||
AIFlag |= (caught ? sound::attachcoupler : 0);
|
||||
// coupled, or locked until the vehicles part, so they don't couple as soon as the collision slows them down
|
||||
thiscoupler.AutomaticCouplingAllowed = safe && false == caught;
|
||||
othercoupler.AutomaticCouplingAllowed = safe && false == caught;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (thiscoupler.CouplingFlag != coupling::faux)
|
||||
{
|
||||
// uzgadnianie prawa Newtona
|
||||
othervehicle->Couplers[1 - End].CForce = -CF;
|
||||
// uzgadnianie prawa Newtona, on the coupler of the other vehicle this one is coupled with, along that vehicle's
|
||||
// axis: turned around once more when the vehicles face each other
|
||||
othervehicle->Couplers[otherend].CForce = -CF * DirPatch(End, otherend);
|
||||
}
|
||||
|
||||
return CF;
|
||||
@@ -6875,13 +6929,12 @@ bool TMoverParameters::AutoRelayCheck(void)
|
||||
}
|
||||
else
|
||||
{ // zmieniaj mainctrlactualpos
|
||||
if (DirActive < 0 && TrainType != dt_PseudoDiesel && RList[MainCtrlActualPos + 1].Bn > BackwardsBranchesAllowed)
|
||||
{
|
||||
return false; // nie poprawiamy przy konwersji
|
||||
// return ARC;// bbylo exit; //Ra: to powoduje, że EN57 nie wyłącza się przy IminLo
|
||||
}
|
||||
// running backwards, the motors don't get joined in more branches than allowed (the series connection
|
||||
// alone, usually); the camshaft still goes back down from there (eu07/maszyna#393: it stayed where it
|
||||
// was, the line contactors closed, whatever the driver did with the master controller)
|
||||
auto const backwardslimit{DirActive < 0 && TrainType != dt_PseudoDiesel && RList[MainCtrlActualPos + 1].Bn > BackwardsBranchesAllowed};
|
||||
// main bez samoczynnego rozruchu
|
||||
if (MainCtrlActualPos < std::size(RList) - 1 // crude guard against running out of current fixed table
|
||||
if (false == backwardslimit && MainCtrlActualPos < std::size(RList) - 1 // crude guard against running out of current fixed table
|
||||
&& (RList[MainCtrlActualPos].Relay < MainCtrlPos || (RList[MainCtrlActualPos + 1].Relay == MainCtrlPos && MainCtrlActualPos < RlistSize) ||
|
||||
(TrainType == dt_ET22 && DelayCtrlFlag)))
|
||||
{
|
||||
@@ -10469,7 +10522,10 @@ void TMoverParameters::LoadFIZ_Brake(std::string const &line)
|
||||
P2FTrans = 0;
|
||||
}
|
||||
|
||||
CntrlPipePress = 5 + 0.001 * (Random(10) - Random(10)); // Ra 2014-07: trochę niedokładności
|
||||
// Ra 2014-07: trochę niedokładności
|
||||
// the draws are sequenced: the order of the operands of '-' is unspecified, and GCC and MSVC draw them the other way round
|
||||
auto const firstdraw{Random(10)};
|
||||
CntrlPipePress = 5 + 0.001 * (Random(10) - firstdraw);
|
||||
extract_value(CntrlPipePress, "HiPP", line, "");
|
||||
HighPipePress = CntrlPipePress;
|
||||
LowPipePress = std::min(HighPipePress, 3.5);
|
||||
@@ -10508,6 +10564,7 @@ void TMoverParameters::LoadFIZ_Brake(std::string const &line)
|
||||
auto lookup = compressorpowers.find(extract_value("CompressorPower", line));
|
||||
CompressorPower = lookup != compressorpowers.end() ? lookup->second : 1;
|
||||
}
|
||||
extract_value(CompressorStartDelay, "CompressorStartDelay", line, "");
|
||||
|
||||
if (true == extract_value(AirLeakRate, "AirLeakRate", line, ""))
|
||||
{
|
||||
@@ -10686,12 +10743,15 @@ void TMoverParameters::LoadFIZ_BuffCoupl(std::string const &line, int const Inde
|
||||
coupler->beta = 0.55;
|
||||
*/
|
||||
thiscoupler->SpringKC = 4500 * 1000;
|
||||
thiscoupler->DmaxC = 0.05;
|
||||
thiscoupler->FmaxC = 850 * 1000;
|
||||
thiscoupler->SpringKB = 9200 * 1000;
|
||||
thiscoupler->DmaxB = 0.05;
|
||||
thiscoupler->FmaxB = 320 * 1000;
|
||||
thiscoupler->beta = 0.55;
|
||||
// the spring force is taken up to Dmax only, past it the vehicles collide (CollisionDetect()); so the joint
|
||||
// carries the full FmaxC either way before it gives. with 0.05 m it carried 225 kN, short of what a loaded
|
||||
// articulated wagon in a freight train takes, which then collided at every step (eu07/maszyna#553)
|
||||
thiscoupler->DmaxC = std::max(0.05, thiscoupler->FmaxC / thiscoupler->SpringKC);
|
||||
thiscoupler->DmaxB = std::max(0.05, thiscoupler->FmaxC / thiscoupler->SpringKB);
|
||||
}
|
||||
|
||||
if (Index == 0)
|
||||
@@ -10724,7 +10784,7 @@ void TMoverParameters::LoadFIZ_Cntrl(std::string const &line)
|
||||
for (int idx = 0; idx < 4; ++idx)
|
||||
{
|
||||
|
||||
extract_value(BrakeDelay[idx], "BDelay" + std::to_string(idx + 1), line, "");
|
||||
extract_value(BrakeDelay[idx], std::format("BDelay{}", idx + 1), line, "");
|
||||
}
|
||||
// brakedelays, brakedelayflag
|
||||
{
|
||||
@@ -10820,6 +10880,16 @@ void TMoverParameters::LoadFIZ_Cntrl(std::string const &line)
|
||||
// maksymalna predkosc dostepna na tarczce predkosciomierza
|
||||
extract_value(maxTachoSpeed, "MaxTachoSpeed", line, "");
|
||||
|
||||
// horns
|
||||
{
|
||||
using enum horn_supply;
|
||||
std::map<std::string, horn_supply, std::less<>> const hornsupplies{{"Pneumatic", air}, {"Electric", electric}};
|
||||
auto lookup = hornsupplies.find(extract_value("HornType", line));
|
||||
HornSupply = lookup != hornsupplies.end() ? lookup->second : air;
|
||||
lookup = hornsupplies.find(extract_value("Horn3Type", line));
|
||||
Horn3Supply = lookup != hornsupplies.end() ? lookup->second : HornSupply;
|
||||
}
|
||||
|
||||
// dynamicbrake
|
||||
{
|
||||
std::map<std::string, int, std::less<>> dynamicbrakes{{"Passive", dbrake_passive}, {"Switch", dbrake_switch}, {"Reversal", dbrake_reversal}, {"Automatic", dbrake_automatic}};
|
||||
@@ -10979,14 +11049,15 @@ void TMoverParameters::LoadFIZ_Cntrl(std::string const &line)
|
||||
// ground relay
|
||||
{
|
||||
auto lookup = starts.find(extract_value("GroundRelayStart", line));
|
||||
GroundRelayStart = lookup != starts.end() ? lookup->second : TrainType == dt_EZT ? start_t::automatic : start_t::manual;
|
||||
auto const defaultstart{TrainType == dt_EZT ? start_t::automatic : start_t::manual};
|
||||
GroundRelayStart = lookup != starts.end() ? lookup->second : defaultstart;
|
||||
}
|
||||
// converter overload relay
|
||||
{
|
||||
auto lookup = starts.find(extract_value("ConverterOverloadRelayStart", line));
|
||||
ConverterOverloadRelayStart = lookup != starts.end() ? lookup->second :
|
||||
TrainType == dt_EZT ? start_t::converter : // relay activates when converter is switched off
|
||||
start_t::manual;
|
||||
// the relay of a multiple unit activates when the converter is switched off
|
||||
auto const defaultstart{TrainType == dt_EZT ? start_t::converter : start_t::manual};
|
||||
ConverterOverloadRelayStart = lookup != starts.end() ? lookup->second : defaultstart;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11379,6 +11450,7 @@ void TMoverParameters::LoadFIZ_Switches(std::string const &Input)
|
||||
extract_value(PantSwitchType, "Pantograph", Input, "");
|
||||
extract_value(ConvSwitchType, "Converter", Input, "");
|
||||
extract_value(StLinSwitchType, "MotorConnectors", Input, "");
|
||||
HeatingSwitchImpulse = ToLower(extract_value("TrainHeating", Input)) == "impulse";
|
||||
// because people can't make up their minds whether it's "impulse" or "Impulse"...
|
||||
PantSwitchType = ToLower(PantSwitchType);
|
||||
ConvSwitchType = ToLower(ConvSwitchType);
|
||||
|
||||
Reference in New Issue
Block a user