16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-20 12:39:17 +02:00

build 170427. improved multi-unit simulation accuracy, high voltage couplers modification

This commit is contained in:
tmj-fstate
2017-04-28 02:59:51 +02:00
parent 1cd39514a1
commit 3e000eae29
5 changed files with 490 additions and 331 deletions

View File

@@ -798,7 +798,7 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
btnOn = true;
}
// else btCPass2.TurnOff();
if (MoverParameters->Battery)
if (MoverParameters->Battery || MoverParameters->ConverterFlag)
{ // sygnaly konca pociagu
if (btEndSignals1.Active())
{
@@ -900,7 +900,7 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
// Ra: przechyłkę załatwiamy na etapie przesuwania modelu
// if (ObjSqrDist<80000) ABuModelRoll(); //przechyłki od 400m
}
if (MoverParameters->Battery)
if( MoverParameters->Battery || MoverParameters->ConverterFlag )
{ // sygnały czoła pociagu //Ra: wyświetlamy bez
// ograniczeń odległości, by były widoczne z
// daleka
@@ -1778,9 +1778,9 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
MoverParameters->PipePress = 0.0;
MoverParameters->Pipe2->CreatePress(0.0);
MoverParameters->ScndPipePress = 0.0;
MoverParameters->PantVolume = 1;
MoverParameters->PantPress = 0;
MoverParameters->CompressedVolume = 0;
MoverParameters->PantVolume = 0.1;
MoverParameters->PantPress = 0.0;
MoverParameters->CompressedVolume = 0.0;
}
if (ActPar.find('1') != std::string::npos) // wylaczanie 10%
@@ -2456,30 +2456,41 @@ bool TDynamicObject::Update(double dt, double dt1)
// McZapkie-260202
if ((MoverParameters->EnginePowerSource.SourceType == CurrentCollector) &&
(MoverParameters->Power > 1.0)) // aby rozrządczy nie opuszczał silnikowemu
/*
if ((MechInside) || (MoverParameters->TrainType == dt_EZT))
{
*/
// if
// ((!MoverParameters->PantCompFlag)&&(MoverParameters->CompressedVolume>=2.8))
// MoverParameters->PantVolume=MoverParameters->CompressedVolume;
if (MoverParameters->PantPress < (MoverParameters->TrainType == dt_EZT ? 2.4 : 3.5))
{ // 3.5 wg
// http://www.transportszynowy.pl/eu06-07pneumat.php
//"Wyłączniki ciśnieniowe odbieraków prądu wyłączają sterowanie
// wyłącznika szybkiego
// oraz uniemożliwiają podniesienie odbieraków prądu, gdy w instalacji
// rozrządu
// ciśnienie spadnie poniżej wartości 3,5 bara."
if( MoverParameters->PantPress < ( MoverParameters->TrainType == dt_EZT ? 2.5 : 3.5 ) ) {
// 3.5 wg http://www.transportszynowy.pl/eu06-07pneumat.php
// Ra 2013-12: Niebugocław mówi, że w EZT podnoszą się przy 2.5
// if (!MoverParameters->PantCompFlag)
// MoverParameters->PantVolume=MoverParameters->CompressedVolume;
MoverParameters->PantFront(false); // opuszczenie pantografów przy niskim ciśnieniu
MoverParameters->PantRear(false); // to idzie w ukrotnieniu, a nie powinno...
if( true == MoverParameters->PantPressSwitchActive ) {
// opuszczenie pantografów przy niskim ciśnieniu
MoverParameters->PantFront( false, MoverParameters->TrainType == dt_EZT );
MoverParameters->PantRear( false, MoverParameters->TrainType == dt_EZT );
// pressure switch safety measure -- open the line breaker, unless there's alternate source of traction voltage
if( MoverParameters->GetTrainsetVoltage() == 0.0 ) {
MoverParameters->MainSwitch( false, false );
}
// mark the pressure switch as spent
MoverParameters->PantPressSwitchActive = false;
}
}
// Winger - automatyczne wylaczanie malej sprezarki
else if (MoverParameters->PantPress >= 4.8)
MoverParameters->PantCompFlag = false;
} // Ra: do Mover to trzeba przenieść, żeby AI też mogło sobie podpompować
else {
// prime the pressure switch
// TODO: check what decides whether the pressure switch is active, prototypically
MoverParameters->PantPressSwitchActive = true;
if( MoverParameters->PantPress >= 4.8 ) {
// Winger - automatyczne wylaczanie malej sprezarki
MoverParameters->PantCompFlag = false;
}
}
/*
} // Ra: do Mover to trzeba przenieść, żeby AI też mogło sobie podpompować
*/
double dDOMoveLen;
TLocation l;
@@ -2911,14 +2922,25 @@ bool TDynamicObject::Update(double dt, double dt1)
// fragment "z EXE Kursa"
if (MoverParameters->Mains) // nie wchodzić w funkcję bez potrzeby
if ( ( false == MoverParameters->Battery)
if ( ( false == MoverParameters->Battery )
&& ( false == MoverParameters->ConverterFlag ) // added alternative power source. TODO: more generic power check
&& ( Controller == Humandriver)
/*
// NOTE: disabled on account of multi-unit setups, where the unmanned unit wouldn't be affected
&& ( Controller == Humandriver )
*/
&& ( MoverParameters->EngineType != DieselEngine )
&& ( MoverParameters->EngineType != WheelsDriven ) )
{ // jeśli bateria wyłączona, a nie diesel ani drezyna reczna
if (MoverParameters->MainSwitch(false)) // wyłączyć zasilanie
if( MoverParameters->MainSwitch( false, MoverParameters->TrainType == dt_EZT ) ) {
// wyłączyć zasilanie
// NOTE: we turn off entire EMU, but only the affected unit for other multi-unit consists
MoverParameters->EventFlag = true;
// drop pantographs
// NOTE: this isn't universal behaviour
// TODO: have this dependant on .fiz-driven flag
MoverParameters->PantFront( false, MoverParameters->TrainType == dt_EZT );
MoverParameters->PantRear( false, MoverParameters->TrainType == dt_EZT );
}
}
if (MoverParameters->TrainType == dt_ET42)
{ // powinny być wszystkie dwuczłony oraz EZT
@@ -3210,21 +3232,23 @@ bool TDynamicObject::Update(double dt, double dt1)
MoverParameters->PantRearVolt = 0.0;
break;
} // pozostałe na razie nie obsługiwane
if (MoverParameters->PantPress >
(MoverParameters->TrainType == dt_EZT ? 2.5 : 3.3)) // Ra 2013-12:
// Niebugocław
// mówi, że w EZT
// podnoszą się
// przy 2.5
pantspeedfactor = 0.015 * (MoverParameters->PantPress) *
dt1; // z EXE Kursa //Ra: wysokość zależy od ciśnienia !!!
else
if( MoverParameters->PantPress > (
MoverParameters->TrainType == dt_EZT ?
2.45 : // Ra 2013-12: Niebugocław mówi, że w EZT podnoszą się przy 2.5
3.45 ) ) {
// z EXE Kursa
// Ra: wysokość zależy od ciśnienia !!!
pantspeedfactor = 0.015 * ( MoverParameters->PantPress ) * dt1;
}
else {
pantspeedfactor = 0.0;
if (pantspeedfactor < 0)
pantspeedfactor = 0;
}
pantspeedfactor = std::max( 0.0, pantspeedfactor );
k = p->fAngleL;
if (i ? MoverParameters->PantRearUp :
MoverParameters->PantFrontUp) // jeśli ma być podniesiony
if( ( pantspeedfactor > 0.0 )
&& ( i ?
MoverParameters->PantRearUp :
MoverParameters->PantFrontUp ) )// jeśli ma być podniesiony
{
if (PantDiff > 0.001) // jeśli nie dolega do drutu
{ // jeśli poprzednia wysokość jest mniejsza niż pożądana, zwiększyć kąt

View File

@@ -139,7 +139,17 @@ static int const ctrain_passenger = 16; //mostek przejściowy
static int const ctrain_scndpneumatic = 32; //przewody 8 atm (żółte; zasilanie powietrzem)
static int const ctrain_heating = 64; //przewody ogrzewania WN
static int const ctrain_depot = 128; //nie rozłączalny podczas zwykłych manewrów (międzyczłonowy), we wpisie wartość ujemna
enum coupling {
faux = 0x0,
coupler = 0x1,
brakehose = 0x2,
control = 0x4,
highvoltage = 0x8,
gangway = 0x10,
mainhose = 0x20,
heating = 0x40,
permanent = 0x80
};
/*typ hamulca elektrodynamicznego*/
static int const dbrake_none = 0;
static int const dbrake_passive = 1;
@@ -360,14 +370,14 @@ struct TBoilerType {
};
/*rodzaj odbieraka pradu*/
struct TCurrentCollector {
long CollectorsNo; //musi być tu, bo inaczej się kopie
double MinH; double MaxH; //zakres ruchu pantografu, nigdzie nie używany
double CSW; //szerokość części roboczej (styku) ślizgacza
double MinV; double MaxV; //minimalne i maksymalne akceptowane napięcie
double OVP; //czy jest przekaznik nadnapieciowy
double InsetV; //minimalne napięcie wymagane do załączenia
double MinPress; //minimalne ciśnienie do załączenia WS
double MaxPress; //maksymalne ciśnienie za reduktorem
long CollectorsNo{ 0.0 }; //musi być tu, bo inaczej się kopie
double MinH{ 0.0 }; double MaxH{ 0.0 }; //zakres ruchu pantografu, nigdzie nie używany
double CSW{ 0.0 }; //szerokość części roboczej (styku) ślizgacza
double MinV{ 0.0 }; double MaxV{ 0.0 }; //minimalne i maksymalne akceptowane napięcie
double OVP{ 0.0 }; //czy jest przekaznik nadnapieciowy
double InsetV{ 0.0 }; //minimalne napięcie wymagane do załączenia
double MinPress{ 0.0 }; //minimalne ciśnienie do załączenia WS
double MaxPress{ 0.0 }; //maksymalne ciśnienie za reduktorem
//inline TCurrentCollector() {
// CollectorsNo = 0;
// MinH, MaxH, CSW, MinV, MaxV = 0.0;
@@ -536,6 +546,11 @@ struct TTransmision
enum TCouplerType { NoCoupler, Articulated, Bare, Chain, Screw, Automatic };
struct power_coupling {
double outgoing{ 0.0 }; // power generated by coupling owner
double incoming{ 0.0 }; // power supplied from outside source
};
struct TCoupling {
/*parametry*/
double SpringKB = 1.0; /*stala sprezystosci zderzaka/sprzegu, %tlumiennosci */
@@ -556,6 +571,9 @@ struct TCoupling {
double CForce = 0.0; /*sila z jaka dzialal*/
double Dist = 0.0; /*strzalka ugiecia zderzaków*/
bool CheckCollision = false; /*czy sprawdzac sile czy pedy*/
power_coupling power_high;
power_coupling power_low; // TODO: implement this
};
class TMoverParameters
@@ -768,7 +786,17 @@ public:
TRotation Rot;
std::string Name; /*nazwa wlasna*/
TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami
double HVCouplers[2][2]; //przewod WN
enum side {
front = 0,
rear
};
#ifdef EU07_USE_OLD_HVCOUPLERS
double HVCouplers[ 2 ][ 2 ]; //przewod WN
enum hvcoupler {
incoming = 0,
outgoing
};
#endif
int ScanCounter = 0; /*pomocnicze do skanowania sprzegow*/
bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/
int SoundFlag = 0; /*!o patrz stale sound_ */
@@ -804,6 +832,7 @@ public:
bool CompressorFlag = false; /*!o czy wlaczona sprezarka*/
bool PantCompFlag = false; /*!o czy wlaczona sprezarka pantografow*/
bool CompressorAllow = false; /*! zezwolenie na uruchomienie sprezarki NBMX*/
bool CompressorGovernorLock{ false }; // indicates whether compressor pressure switch was activated due to reaching cut-out pressure
bool ConverterFlag = false ; /*! czy wlaczona przetwornica NBMX*/
bool ConverterAllow = false; /*zezwolenie na prace przetwornicy NBMX*/
int BrakeCtrlPos = -2; /*nastawa hamulca zespolonego*/
@@ -886,7 +915,8 @@ public:
double RventRot = 0.0; /*!s obroty wentylatorow rozruchowych*/
bool UnBrake = false; /*w EZT - nacisniete odhamowywanie*/
double PantPress = 0.0; /*Cisnienie w zbiornikach pantografow*/
bool s_CAtestebrake = false; //hunter-091012: zmienna dla testu ca
bool PantPressSwitchActive{ false }; // state of the pantograph pressure switch. gets primed when the pantograph is up
bool s_CAtestebrake = false; //hunter-091012: zmienna dla testu ca
/*-zmienne dla lokomotywy spalinowej z przekladnia mechaniczna*/
double dizel_fill = 0.0; /*napelnienie*/
@@ -1058,7 +1088,7 @@ public:
/*--funkcje dla lokomotyw*/
bool DirectionBackward(void);/*! kierunek ruchu*/
bool MainSwitch(bool State);/*! wylacznik glowny*/
bool MainSwitch( bool const State, bool const Multiunitcontrol = true );/*! wylacznik glowny*/
bool ConverterSwitch(bool State);/*! wl/wyl przetwornicy*/
bool CompressorSwitch(bool State);/*! wl/wyl sprezarki*/
@@ -1086,8 +1116,8 @@ public:
bool AutoRelayCheck(void);//symulacja automatycznego rozruchu
bool ResistorsFlagCheck(void); //sprawdzenie kontrolki oporow rozruchowych NBMX
bool PantFront(bool State); //obsluga pantografou przedniego
bool PantRear(bool State); //obsluga pantografu tylnego
bool PantFront(bool const State, bool const Multiunitcontrol = true ); //obsluga pantografou przedniego
bool PantRear(bool const State, bool const Multiunitcontrol = true ); //obsluga pantografu tylnego
/*-funkcje typowe dla lokomotywy spalinowej z przekladnia mechaniczna*/
bool dizel_EngageSwitch(double state);

View File

@@ -337,11 +337,12 @@ Name( NameInit )
Couplers[b].DmaxC = 0.1;
Couplers[b].FmaxC = 1000.0;
}
for(int b = 0; b < 2; ++b ) {
#ifdef EU07_USE_OLD_HVCOUPLERS
for( int b = 0; b < 2; ++b ) {
HVCouplers[ b ][ 0 ] = 0.0;
HVCouplers[ b ][ 1 ] = 0.0;
}
#endif
for( int b = 0; b < 3; ++b ) {
BrakeCylMult[ b ] = 0.0;
}
@@ -709,21 +710,19 @@ void TMoverParameters::UpdatePantVolume(double dt)
// nie tak
if (EnginePowerSource.SourceType == CurrentCollector) // tylko jeśli pantografujący
{
// Ra 2014-07: zasadniczo, to istnieje zbiornik rozrządu i zbiornik pantografów - na razie
// mamy razem
// Ra 2014-07: kurek trójdrogowy łączy spr.pom. z pantografami i wyłącznikiem ciśnieniowym
// WS
// Ra 2014-07: zasadniczo, to istnieje zbiornik rozrządu i zbiornik pantografów - na razie mamy razem
// Ra 2014-07: kurek trójdrogowy łączy spr.pom. z pantografami i wyłącznikiem ciśnieniowym WS
// Ra 2014-07: zbiornika rozrządu nie pompuje się tu, tylko pantografy; potem można zamknąć
// WS i odpalić resztę
// NOTE: custom variant for EMU disabled because it pretty much doesn't work
if ((TrainType == dt_EZT) ? (PantPress < ScndPipePress) :
bPantKurek3) // kurek zamyka połączenie z ZG
{ // zbiornik pantografu połączony ze zbiornikiem głównym - małą sprężarką się tego nie
// napompuje
{ // zbiornik pantografu połączony ze zbiornikiem głównym - małą sprężarką się tego nie napompuje
// Ra 2013-12: Niebugocław mówi, że w EZT nie ma potrzeby odcinać kurkiem
PantPress = EnginePowerSource.CollectorParameters
.MaxPress; // ograniczenie ciśnienia do MaxPress (tylko w pantografach!)
if (PantPress > ScndPipePress)
PantPress = ScndPipePress; // oraz do ScndPipePress
PantPress = ScndPipePress;
// ograniczenie ciśnienia do MaxPress (tylko w pantografach!)
PantPress = std::min( PantPress, EnginePowerSource.CollectorParameters.MaxPress );
PantPress = std::max( PantPress, 0.0 );
PantVolume = (PantPress + 1.0) * 0.1; // objętość, na wypadek odcięcia kurkiem
}
else
@@ -733,19 +732,34 @@ void TMoverParameters::UpdatePantVolume(double dt)
(2.0 * 0.45 - ((0.1 / PantVolume / 10) - 0.1)) /
0.45; // napełnianie zbiornika pantografów
// Ra 2013-12: Niebugocław mówi, że w EZT nabija 1.5 raz wolniej niż jak było 0.005
PantPress = (10.0 * PantVolume) - 1.0; // tu by się przydała objętość zbiornika
PantPress = std::min( (10.0 * PantVolume) - 1.0, EnginePowerSource.CollectorParameters.MaxPress ); // tu by się przydała objętość zbiornika
PantPress = std::max( PantPress, 0.0 );
}
if (!PantCompFlag && (PantVolume > 0.1))
PantVolume -= dt * 0.0003; // nieszczelności: 0.0003=0.3l/s
if (Mains) // nie wchodzić w funkcję bez potrzeby
if (EngineType == ElectricSeriesMotor) // nie dotyczy... czego właściwie?
if (PantPress < EnginePowerSource.CollectorParameters.MinPress)
if ((TrainType & (dt_EZT | dt_ET40 | dt_ET41 | dt_ET42)) ?
(GetTrainsetVoltage() < EnginePowerSource.CollectorParameters.MinV) :
true) // to jest trochę proteza; zasilanie członu może być przez sprzęg
// WN
if (MainSwitch(false))
EventFlag = true; // wywalenie szybkiego z powodu niskiego ciśnienia
if( Mains ) {
// nie wchodzić w funkcję bez potrzeby
if( EngineType == ElectricSeriesMotor ) {
// nie dotyczy... czego właściwie?
if( ( true == PantPressSwitchActive )
&& ( PantPress < EnginePowerSource.CollectorParameters.MinPress ) ) {
// wywalenie szybkiego z powodu niskiego ciśnienia
if( GetTrainsetVoltage() < EnginePowerSource.CollectorParameters.MinV ) {
// to jest trochę proteza; zasilanie członu może być przez sprzęg WN
if( MainSwitch( false, TrainType == dt_EZT ) ) {
EventFlag = true;
}
}
/*
// NOTE: disabled, the flag gets set in dynobj.update() when the pantograph actually drops
// mark the pressure switch as spent, regardless whether line breaker actually opened
PantPressSwitchActive = false;
*/
}
}
}
/*
// NOTE: pantograph tank pressure sharing experimentally disabled for more accurate simulation
if (TrainType != dt_EZT) // w EN57 pompuje się tylko w silnikowym
// pierwotnie w CHK pantografy miały również rozrządcze EZT
for (int b = 0; b <= 1; ++b)
@@ -757,6 +771,7 @@ void TMoverParameters::UpdatePantVolume(double dt)
// czy np. w ET40, ET41, ET42 pantografy członów mają połączenie pneumatyczne?
// Ra 2014-07: raczej nie - najpierw się załącza jeden człon, a potem można podnieść w
// drugim
*/
}
else
{ // a tu coś dla SM42 i SM31, aby pokazywać na manometrze
@@ -1059,57 +1074,99 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
{
const double Vepsilon = 1e-5;
const double Aepsilon = 1e-3; // ASBSpeed=0.8;
int b;
double Vprev, AccSprev, d, hvc;
double Vprev, AccSprev, d;
// T_MoverParameters::ComputeMovement(dt, dt1, Shape, Track, ElectricTraction, NewLoc, NewRot);
// // najpierw kawalek z funkcji w pliku mover.pas
TotalCurrent = 0;
hvc = Max0R(Max0R(PantFrontVolt, PantRearVolt), ElectricTraction.TractionVoltage * 0.9);
for (b = 0; b < 2; b++) // przekazywanie napiec
if (((Couplers[b].CouplingFlag & ctrain_power) == ctrain_power) ||
(((Couplers[b].CouplingFlag & ctrain_heating) == ctrain_heating) && (Heating)))
{
HVCouplers[1 - b][1] =
Max0R(abs(hvc), Couplers[b].Connected->HVCouplers[Couplers[b].ConnectedNr][1] -
HVCouplers[b][0] * 0.02);
double hvc =
std::max(
std::max(
PantFrontVolt,
PantRearVolt ),
ElectricTraction.TractionVoltage * 0.9 );
for( int side = 0; side < 2; ++side ) {
// przekazywanie napiec
auto const oppositeside = ( side == side::front ? side::rear : side::front );
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|| ( ( Heating )
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
#ifdef EU07_USE_OLD_HVCOUPLERS
HVCouplers[ oppositeside ][ hvcoupler::outgoing ] =
std::max(
std::abs( hvc ),
Couplers[ side ].Connected->HVCouplers[ Couplers[ side ].ConnectedNr ][ hvcoupler::outgoing ] - HVCouplers[ side ][ hvcoupler::incoming ] * 0.02 );
#else
auto const &connectedcoupler = Couplers[ side ].Connected->Couplers[ Couplers[ side ].ConnectedNr ];
Couplers[ oppositeside ].power_high.outgoing =
std::max(
std::abs( hvc ),
connectedcoupler.power_high.outgoing - Couplers[ side ].power_high.incoming * 0.02 );
#endif
}
else
HVCouplers[1 - b][1] = abs(hvc) - HVCouplers[b][0] * 0.02;
// Max0R(Abs(Voltage),0);
// end;
else {
#ifdef EU07_USE_OLD_HVCOUPLERS
HVCouplers[ oppositeside ][ hvcoupler::outgoing ] = abs( hvc ) - HVCouplers[ side ][ hvcoupler::incoming ] * 0.02;
#else
Couplers[ oppositeside ].power_high.outgoing = std::abs( hvc ) - Couplers[ side ].power_high.incoming * 0.02;
#endif
}
}
hvc = HVCouplers[0][1] + HVCouplers[1][1];
#ifdef EU07_USE_OLD_HVCOUPLERS
hvc = HVCouplers[ side::front ][ hvcoupler::outgoing ] + HVCouplers[ side::rear ][ hvcoupler::outgoing ];
#else
hvc = Couplers[ side::front ].power_high.outgoing + Couplers[ side::rear ].power_high.outgoing;
#endif
if ((abs(PantFrontVolt) + abs(PantRearVolt) < 1) &&
(hvc > 1)) // bez napiecia, ale jest cos na sprzegach:
{
for (b = 0; b < 2; ++b) // przekazywanie pradow
if (((Couplers[b].CouplingFlag & ctrain_power) == ctrain_power) ||
(((Couplers[b].CouplingFlag & ctrain_heating) == ctrain_heating) &&
(Heating))) // jesli spiety
{
HVCouplers[b][0] =
Couplers[b].Connected->HVCouplers[1 - Couplers[b].ConnectedNr][0] +
Itot * HVCouplers[b][1] / hvc; // obciążenie rozkladane stosownie do napiec
}
else // pierwszy pojazd
{
HVCouplers[b][0] = Itot * HVCouplers[b][1] / hvc;
}
if( ( std::abs( PantFrontVolt ) + std::abs( PantRearVolt ) < 1.0 )
&& ( hvc > 1.0 ) ) {
// bez napiecia, ale jest cos na sprzegach:
// przekazywanie pradow
for( int side = 0; side < 2; ++side ) {
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|| ( ( Heating )
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
#ifdef EU07_USE_OLD_HVCOUPLERS
HVCouplers[ side ][ hvcoupler::incoming ] =
Couplers[side].Connected->HVCouplers[Couplers[side].ConnectedNr][hvcoupler::outgoing] +
Itot * HVCouplers[side][hvcoupler::outgoing] / hvc; // obciążenie rozkladane stosownie do napiec
#else
auto const &connectedcoupler = Couplers[ side ].Connected->Couplers[ Couplers[ side ].ConnectedNr ];
Couplers[ side ].power_high.incoming =
connectedcoupler.power_high.outgoing
+ Itot * Couplers[ side ].power_high.outgoing / hvc; // obciążenie rozkladane stosownie do napiec
#endif
}
else {
#ifdef EU07_USE_OLD_HVCOUPLERS
// pierwszy pojazd
HVCouplers[side][hvcoupler::incoming] = Itot * HVCouplers[side][hvcoupler::outgoing] / hvc;
#else
Couplers[ side ].power_high.incoming = Itot * Couplers[ side ].power_high.outgoing / hvc;
#endif
}
}
}
else
{
if (((Couplers[0].CouplingFlag & ctrain_power) == ctrain_power) ||
(((Couplers[0].CouplingFlag & ctrain_heating) == ctrain_heating) && (Heating)))
TotalCurrent +=
Couplers[0].Connected->HVCouplers[1 - Couplers[0].ConnectedNr][0];
if (((Couplers[1].CouplingFlag & ctrain_power) == ctrain_power) ||
(((Couplers[1].CouplingFlag & ctrain_heating) == ctrain_heating) && (Heating)))
TotalCurrent +=
Couplers[1].Connected->HVCouplers[1 - Couplers[1].ConnectedNr][0];
HVCouplers[0][0] = 0;
HVCouplers[1][0] = 0;
for( int side = 0; side < 2; ++side ) {
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|| ( ( Heating )
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
#ifdef EU07_USE_OLD_HVCOUPLERS
TotalCurrent += Couplers[ side ].Connected->HVCouplers[ Couplers[ side ].ConnectedNr ][ hvcoupler::incoming ];
HVCouplers[ side ][ hvcoupler::incoming ] = 0.0;
#else
auto const &connectedcoupler = Couplers[ side ].Connected->Couplers[ Couplers[ side ].ConnectedNr ];
TotalCurrent += connectedcoupler.power_high.incoming;
Couplers[ side ].power_high.incoming = 0.0;
#endif
}
}
}
if (!TestFlag(DamageFlag, dtrain_out))
@@ -1225,7 +1282,7 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
// przesuniecie
dL = (3.0 * V - Vprev) * dt / 2.0; // metoda Adamsa-Bashfortha}
// ale jesli jest kolizja (zas. zach. pedu) to...}
for (b = 0; b < 2; b++)
for (int b = 0; b < 2; b++)
if (Couplers[b].CheckCollision)
CollisionDetect(b, dt); // zmienia niejawnie AccS, V !!!
@@ -1463,10 +1520,14 @@ double TMoverParameters::ShowEngineRotation(int VehN)
void TMoverParameters::ConverterCheck()
{ // sprawdzanie przetwornicy
if (ConverterAllow && Mains)
if( ( ConverterAllow )
&& ( ( Mains )
|| ( GetTrainsetVoltage() > 0.5 * EnginePowerSource.MaxVoltage ) ) ) {
ConverterFlag = true;
else
}
else {
ConverterFlag = false;
}
};
double TMoverParameters::ShowCurrent(int AmpN)
@@ -2210,7 +2271,7 @@ bool TMoverParameters::AntiSlippingButton(void)
// Q: 20160713
// włączenie / wyłączenie obwodu głownego
// *************************************************************************************************
bool TMoverParameters::MainSwitch(bool State)
bool TMoverParameters::MainSwitch( bool const State, bool const Multiunitcontrol )
{
bool MS;
@@ -2222,13 +2283,21 @@ bool TMoverParameters::MainSwitch(bool State)
(LastSwitchingTime > CtrlDelay) && !TestFlag(DamageFlag, dtrain_out) &&
!TestFlag(EngDmgFlag, 1)))
{
if (Mains) // jeśli był załączony
SendCtrlToNext("MainSwitch", int(State),
CabNo); // wysłanie wyłączenia do pozostałych?
if( Mains ) {
// jeśli był załączony
if( true == Multiunitcontrol ) {
// wysłanie wyłączenia do pozostałych?
SendCtrlToNext( "MainSwitch", int( State ), CabNo );
}
}
Mains = State;
if (Mains) // jeśli został załączony
SendCtrlToNext("MainSwitch", int(State),
CabNo); // wyslanie po wlaczeniu albo przed wylaczeniem
if( Mains ) {
// jeśli został załączony
if( true == Multiunitcontrol ) {
// wyslanie po wlaczeniu albo przed wylaczeniem
SendCtrlToNext( "MainSwitch", int( State ), CabNo );
}
}
MS = true; // wartość zwrotna
LastSwitchingTime = 0;
if ((EngineType == DieselEngine) && Mains)
@@ -2898,15 +2967,21 @@ void TMoverParameters::CompressorCheck(double dt)
else
CompressorFlag = (CompressorAllow) &&
((ConverterFlag) || (CompressorPower == 0)) && (Mains);
if (Compressor >
MaxCompressor) // wyłącznik ciśnieniowy jest niezależny od sposobu zasilania
if( Compressor > MaxCompressor ) {
// wyłącznik ciśnieniowy jest niezależny od sposobu zasilania
CompressorFlag = false;
CompressorGovernorLock = true; // prevent manual activation until the pressure goes below cut-in level
}
}
else // jeśli nie załączona
if ((Compressor < MinCompressor) &&
(LastSwitchingTime > CtrlDelay)) // jeśli nie załączona, a ciśnienie za małe
{ // załączenie przy małym ciśnieniu
if (CompressorPower == 5) // jeśli zasilanie z następnego członu
if( ( ( Compressor < MinCompressor )
|| ( ( Compressor < MaxCompressor )
&& ( false == CompressorGovernorLock ) ) )
&& (LastSwitchingTime > CtrlDelay) ) {
// załączenie przy małym ciśnieniu
// jeśli nie załączona, a ciśnienie za małe
// or if the switch is on and the pressure isn't maxed
if( CompressorPower == 5 ) // jeśli zasilanie z następnego członu
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
if (Couplers[1].Connected != NULL)
CompressorFlag =
@@ -2927,8 +3002,14 @@ void TMoverParameters::CompressorCheck(double dt)
else
CompressorFlag = (CompressorAllow) &&
((ConverterFlag) || (CompressorPower == 0)) && (Mains);
if (CompressorFlag) // jeśli została załączona
if( CompressorFlag ) {
// jeśli została załączona
LastSwitchingTime = 0; // to trzeba ograniczyć ponowne włączenie
if( Compressor < MinCompressor ) {
// if the activation took place at pressure below the cut-in level, we can reset compressor governor
CompressorGovernorLock = false;
}
}
}
// for b:=0 to 1 do //z Megapacka
// with Couplers[b] do
@@ -3231,14 +3312,17 @@ void TMoverParameters::UpdateScndPipePressure(double dt)
}
Pipe2->Flow(Hamulec->GetHPFlow(ScndPipePress, dt));
/*
// NOTE: condition disabled to allow the air flow from the main hose to the main tank as well
if (((Compressor > ScndPipePress) && (CompressorSpeed > 0.0001)) || (TrainType == dt_EZT))
{
*/
dV = PF(Compressor, ScndPipePress, Spz) * dt;
CompressedVolume += dV / 1000.0;
Pipe2->Flow(-dV);
/*
}
*/
Pipe2->Flow(dv1 + dv2);
Pipe2->Act();
ScndPipePress = Pipe2->P();
@@ -3407,21 +3491,27 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer)
LastSwitchingTime += dt1;
if (EngineType == ElectricSeriesMotor)
LastRelayTime += dt1;
if (Mains && /*(abs(CabNo) < 2) &&*/ (EngineType ==
ElectricSeriesMotor)) // potem ulepszyc! pantogtrafy!
if( Mains && /*(abs(CabNo) < 2) &&*/ ( EngineType ==
ElectricSeriesMotor ) ) // potem ulepszyc! pantogtrafy!
{ // Ra 2014-03: uwzględnienie kierunku jazdy w napięciu na silnikach, a powinien być
// zdefiniowany nawrotnik
if (CabNo == 0)
// zdefiniowany nawrotnik
if( CabNo == 0 )
Voltage = RunningTraction.TractionVoltage * ActiveDir;
else
Voltage = RunningTraction.TractionVoltage * DirAbsolute; // ActiveDir*CabNo;
} // bo nie dzialalo
else if ((EngineType == ElectricInductionMotor) ||
(((Couplers[0].CouplingFlag & ctrain_power) == ctrain_power) ||
((Couplers[1].CouplingFlag & ctrain_power) ==
ctrain_power))) // potem ulepszyc! pantogtrafy!
Voltage =
Max0R(Max0R(RunningTraction.TractionVoltage, HVCouplers[0][1]), HVCouplers[1][1]);
else if( ( EngineType == ElectricInductionMotor ) ||
( ( ( Couplers[ 0 ].CouplingFlag & ctrain_power ) == ctrain_power ) ||
( ( Couplers[ 1 ].CouplingFlag & ctrain_power ) ==
ctrain_power ) ) ) // potem ulepszyc! pantogtrafy!
Voltage =
std::max(
RunningTraction.TractionVoltage,
#ifdef EU07_USE_OLD_HVCOUPLERS
std::max( HVCouplers[side::front][hvcoupler::incoming], HVCouplers[side::rear][hvcoupler::incoming] ) );
#else
std::max( Couplers[ side::front ].power_high.incoming, Couplers[ side::rear ].power_high.incoming ) );
#endif
else
Voltage = 0;
//if (Mains && /*(abs(CabNo) < 2) &&*/ (
@@ -3975,10 +4065,10 @@ double TMoverParameters::TractionForce(double dt)
FuseOff(); // wywalanie bezpiecznika z powodu przetezenia silnikow
if ((Mains)) // nie wchodzić w funkcję bez potrzeby
if ((abs(Voltage) < EnginePowerSource.CollectorParameters.MinV) ||
(abs(Voltage) * EnginePowerSource.CollectorParameters.OVP >
if ( (std::max(GetTrainsetVoltage(), std::abs(Voltage)) < EnginePowerSource.CollectorParameters.MinV) ||
(std::max(GetTrainsetVoltage(), std::abs(Voltage)) * EnginePowerSource.CollectorParameters.OVP >
EnginePowerSource.CollectorParameters.MaxV))
if (MainSwitch(false))
if (MainSwitch(false, TrainType == dt_EZT)) // TODO: check whether we need to send this EMU-wide
EventFlag = true; // wywalanie szybkiego z powodu niewłaściwego napięcia
if (((DynamicBrakeType == dbrake_automatic) || (DynamicBrakeType == dbrake_switch)) &&
@@ -4263,11 +4353,11 @@ double TMoverParameters::TractionForce(double dt)
{
if( ( Mains ) ) {
// nie wchodzić w funkcję bez potrzeby
if( ( abs( Voltage ) < EnginePowerSource.CollectorParameters.MinV )
|| ( abs( Voltage ) > EnginePowerSource.CollectorParameters.MaxV + 200 ) ) {
MainSwitch( false );
}
if( ( std::max( std::abs( Voltage ), GetTrainsetVoltage() ) < EnginePowerSource.CollectorParameters.MinV )
|| ( std::max( std::abs( Voltage ), GetTrainsetVoltage() ) > EnginePowerSource.CollectorParameters.MaxV + 200 ) ) {
MainSwitch( false, TrainType == dt_EZT ); // TODO: check whether we need to send this EMU-wide
}
}
tmpV = abs(nrot) * (PI * WheelDiameter) * 3.6; //*DirAbsolute*eimc[eimc_s_p]; - do przemyslenia dzialanie pp
if ((Mains))
{
@@ -4979,23 +5069,29 @@ bool TMoverParameters::AutoRelayCheck(void)
// Q: 20160713
// Podnosi / opuszcza przedni pantograf. Returns: state of the pantograph after the operation
// *************************************************************************************************
bool TMoverParameters::PantFront(bool State)
bool TMoverParameters::PantFront(bool const State, bool const Multiunitcontrol)
{
/*
if( ( true == Battery )
|| ( true == ConverterFlag ) ) {
*/
if( PantFrontUp != State ) {
PantFrontUp = State;
if( State == true ) {
PantFrontStart = 0;
SendCtrlToNext( "PantFront", 1, CabNo );
if( true == Multiunitcontrol ) {
SendCtrlToNext( "PantFront", 1, CabNo );
}
}
else {
PantFrontStart = 1;
SendCtrlToNext( "PantFront", 0, CabNo );
}
if( true == Multiunitcontrol ) {
SendCtrlToNext( "PantFront", 0, CabNo );
}
}
}
/*
}
else {
// no power, drop the pantograph
// NOTE: this is a simplification as it should just drop on its own with loss of pressure without resupply from (dead) compressor
@@ -5004,9 +5100,11 @@ bool TMoverParameters::PantFront(bool State)
1 :
0 );
PantFrontUp = false;
SendCtrlToNext( "PantFront", 0, CabNo );
if( true == Multiunitcontrol ) {
SendCtrlToNext( "PantFront", 0, CabNo );
}
}
*/
return PantFrontUp;
}
@@ -5014,23 +5112,29 @@ bool TMoverParameters::PantFront(bool State)
// Q: 20160713
// Podnoszenie / opuszczanie pantografu tylnego
// *************************************************************************************************
bool TMoverParameters::PantRear(bool State)
bool TMoverParameters::PantRear(bool const State, bool const Multiunitcontrol)
{
/*
if( ( true == Battery )
|| ( true == ConverterFlag ) ) {
*/
if( PantRearUp != State ) {
PantRearUp = State;
if( State == true ) {
PantRearStart = 0;
SendCtrlToNext( "PantRear", 1, CabNo );
if( true == Multiunitcontrol ) {
SendCtrlToNext( "PantRear", 1, CabNo );
}
}
else {
PantRearStart = 1;
SendCtrlToNext( "PantRear", 0, CabNo );
}
if( true == Multiunitcontrol ) {
SendCtrlToNext( "PantRear", 0, CabNo );
}
}
}
/*
}
else {
// no power, drop the pantograph
// NOTE: this is a simplification as it should just drop on its own with loss of pressure without resupply from (dead) compressor
@@ -5039,9 +5143,11 @@ bool TMoverParameters::PantRear(bool State)
1 :
0 );
PantRearUp = false;
SendCtrlToNext( "PantRear", 0, CabNo );
if( true == Multiunitcontrol ) {
SendCtrlToNext( "PantRear", 0, CabNo );
}
}
*/
return PantRearUp;
}
@@ -5476,7 +5582,7 @@ std::string TMoverParameters::EngineDescription(int what)
case 0:
{
if (DamageFlag == 255)
outstr = "Totally destroyed!";
outstr = "WRECKED";
else
{
if (TestFlag(DamageFlag, dtrain_thinwheel))
@@ -5500,13 +5606,13 @@ std::string TMoverParameters::EngineDescription(int what)
if (Power > 0.1)
outstr = "Engine damaged,";
else
outstr = "Load destroyed!,";
outstr = "LOAD DESTROYED,";
if (TestFlag(DamageFlag, dtrain_axle))
outstr = "Axle broken,";
if (TestFlag(DamageFlag, dtrain_out))
outstr = "DERAILED!";
outstr = "DERAILED";
if (outstr == "")
outstr = "OK!";
outstr = "OK";
}
break;
}
@@ -5523,7 +5629,30 @@ std::string TMoverParameters::EngineDescription(int what)
// *************************************************************************************************
double TMoverParameters::GetTrainsetVoltage(void)
{//ABu: funkcja zwracajaca napiecie dla calego skladu, przydatna dla EZT
return Max0R(HVCouplers[1][1], HVCouplers[0][1]);
/*
return std::min(
std::max( HVCouplers[ 1 ][ 1 ], HVCouplers[ 0 ][ 1 ] ), // local
std::max( HVCouplers[ 1 ][ 0 ], HVCouplers[ 0 ][ 0 ] ) ); // remote
*/
// TODO: investigate what exactly is reported on these couplers, does it include heating?
#ifdef EU07_USE_OLD_HVCOUPLERS
// TODO: if we ever revert to this version, match the expanded alternative below
return std::max( HVCouplers[ 1 ][ 0 ], HVCouplers[ 0 ][ 0 ] ); // incoming, external power
#else
return std::max(
( ( ( Couplers[side::front].Connected )
&& ( ( Couplers[ side::front ].CouplingFlag & ctrain_power )
|| ( ( Heating )
&& ( Couplers[ side::front ].CouplingFlag & ctrain_heating ) ) ) ) ?
Couplers[side::front].Connected->Couplers[ Couplers[side::front].ConnectedNr ].power_high.outgoing :
0.0 ),
( ( ( Couplers[side::rear].Connected )
&& ( ( Couplers[ side::rear ].CouplingFlag & ctrain_power )
|| ( ( Heating )
&& ( Couplers[ side::rear ].CouplingFlag & ctrain_heating ) ) ) ) ?
Couplers[ side::rear ].Connected->Couplers[ Couplers[ side::rear ].ConnectedNr ].power_high.outgoing :
0.0 ) );
#endif
}
// *************************************************************************************************

256
Train.cpp
View File

@@ -1533,6 +1533,10 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com
// press or hold...
if( Train->m_linebreakerstate == 0 ) {
// ...to close the circuit
if( Command.action == GLFW_PRESS ) {
// fresh press, start fresh closing delay calculation
Train->fMainRelayTimer = 0.0f;
}
if( Train->ggMainOnButton.SubModel != nullptr ) {
// two separate switches to close and break the circuit
// audio feedback
@@ -1552,8 +1556,9 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com
Train->ggMainButton.UpdateValue( 1.0 );
}
// keep track of period the button is held down, to determine when/if circuit closes
if( ( false == ( Train->mvControlled->EnginePowerSource.PowerType == ElectricSeriesMotor ) || ( Train->mvControlled->EngineType == ElectricInductionMotor ) )
|| ( Train->fHVoltage > 0.0f ) ) {
if( ( false == ( ( Train->mvControlled->EngineType == ElectricSeriesMotor )
|| ( Train->mvControlled->EngineType == ElectricInductionMotor ) ) )
|| ( Train->fHVoltage > 0.5 * Train->mvControlled->EnginePowerSource.MaxVoltage ) ) {
// prevent the switch from working if there's no power
// TODO: consider whether it makes sense for diesel engines and such
Train->fMainRelayTimer += 0.33f; // Command.time_delta * 5.0;
@@ -1695,6 +1700,8 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com
// finalize the state of the line breaker
Train->m_linebreakerstate = 1;
}
// on button release reset the closing timer, just in case something elsewhere tries to read it
Train->fMainRelayTimer = 0.0f;
}
}
@@ -1705,15 +1712,17 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma
if( ( false == Train->mvControlled->ConverterAllow )
&& ( Train->ggConverterButton.GetValue() < 0.5 ) ) {
// turn on
// sound feedback
if( Train->ggConverterButton.GetValue() < 0.5 ) {
Train->play_sound( Train->dsbSwitch );
}
// visual feedback
Train->ggConverterButton.UpdateValue( 1.0 );
/*
if( ( Train->mvControlled->EnginePowerSource.SourceType != CurrentCollector )
|| ( Train->mvControlled->PantRearVolt != 0.0 )
|| ( Train->mvControlled->PantFrontVolt != 0.0 ) ) {
// visual feedback
Train->ggConverterButton.UpdateValue( 1.0 );
// sound feedback
if( Train->ggConverterButton.GetValue() < 0.5 ) {
Train->play_sound( Train->dsbSwitch );
}
*/
// impulse type switch has no effect if there's no power
// NOTE: this is most likely setup wrong, but the whole thing is smoke and mirrors anyway
if( ( Train->mvOccupied->ConvSwitchType != "impulse" )
@@ -1728,7 +1737,9 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma
}
}
}
/*
}
*/
}
else {
//turn off
@@ -3141,11 +3152,13 @@ if
if (DynamicObject->Mechanik) // na wszelki wypadek
DynamicObject->Mechanik->CheckVehicles(Connect); // aktualizacja flag kierunku w składzie
play_sound( dsbCouplerAttach );
// one coupling type per key press
return;
}
else
WriteLog("Mechanical coupling failed.");
}
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_pneumatic)) // pneumatyka
if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_pneumatic)) // pneumatyka
{
if ((tmp->MoverParameters->Couplers[CouplNr].Connected->Couplers[CouplNr].AllowedFlag
& tmp->MoverParameters->Couplers[CouplNr].AllowedFlag
@@ -3155,12 +3168,16 @@ if
tmp->MoverParameters->Couplers[CouplNr].Connected,
(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_pneumatic)))
{
rsHiss.Play(1, DSBPLAY_LOOPING, true, tmp->GetPosition());
// TODO: dedicated 'click' sound for connecting cable-type connections
play_sound( dsbCouplerDetach );
// rsHiss.Play( 1, DSBPLAY_LOOPING, true, tmp->GetPosition() );
DynamicObject->SetPneumatic(CouplNr != 0, true); // Ra: to mi się nie podoba !!!!
tmp->SetPneumatic(CouplNr != 0, true);
// one coupling type per key press
return;
}
}
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_scndpneumatic)) // zasilajacy
if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_scndpneumatic)) // zasilajacy
{
if ((tmp->MoverParameters->Couplers[CouplNr].Connected->Couplers[CouplNr].AllowedFlag
& tmp->MoverParameters->Couplers[CouplNr].AllowedFlag
@@ -3170,17 +3187,18 @@ if
tmp->MoverParameters->Couplers[CouplNr].Connected,
(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_scndpneumatic)))
{
// rsHiss.Play(1,DSBPLAY_LOOPING,true,tmp->GetPosition());
// TODO: dedicated 'click' sound for connecting cable-type connections
play_sound( dsbCouplerDetach );
DynamicObject->SetPneumatic(CouplNr != 0, false); // Ra: to mi się nie podoba !!!!
// rsHiss.Play( 1, DSBPLAY_LOOPING, true, tmp->GetPosition() );
DynamicObject->SetPneumatic( CouplNr != 0, false ); // Ra: to mi się nie podoba !!!!
tmp->SetPneumatic(CouplNr != 0, false);
// one coupling type per key press
return;
}
}
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_controll)) // ukrotnionko
if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_controll)) // ukrotnionko
{
if ((tmp->MoverParameters->Couplers[CouplNr]
.Connected->Couplers[CouplNr]
.AllowedFlag &
if ((tmp->MoverParameters->Couplers[CouplNr].Connected->Couplers[CouplNr].AllowedFlag &
tmp->MoverParameters->Couplers[CouplNr].AllowedFlag &
ctrain_controll) == ctrain_controll)
if (tmp->MoverParameters->Attach(
@@ -3188,14 +3206,15 @@ if
tmp->MoverParameters->Couplers[CouplNr].Connected,
(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_controll)))
{
// TODO: dedicated 'click' sound for connecting cable-type connections
play_sound( dsbCouplerAttach );
// one coupling type per key press
return;
}
}
else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_passenger)) // mostek
if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_passenger)) // mostek
{
if ((tmp->MoverParameters->Couplers[CouplNr]
.Connected->Couplers[CouplNr]
.AllowedFlag &
if ((tmp->MoverParameters->Couplers[CouplNr].Connected->Couplers[CouplNr].AllowedFlag &
tmp->MoverParameters->Couplers[CouplNr].AllowedFlag &
ctrain_passenger) == ctrain_passenger)
if (tmp->MoverParameters->Attach(
@@ -3203,10 +3222,29 @@ if
tmp->MoverParameters->Couplers[CouplNr].Connected,
(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_passenger)))
{
// rsHiss.Play(1,DSBPLAY_LOOPING,true,tmp->GetPosition());
play_sound( dsbCouplerDetach );
play_sound( dsbCouplerAttach );
/*
DynamicObject->SetPneumatic(CouplNr != 0, false);
tmp->SetPneumatic(CouplNr != 0, false);
*/
// one coupling type per key press
return;
}
}
if( false == TestFlag( tmp->MoverParameters->Couplers[ CouplNr ].CouplingFlag, ctrain_heating ) ) {
// heating
if( ( tmp->MoverParameters->Couplers[ CouplNr ].Connected->Couplers[ CouplNr ].AllowedFlag
& tmp->MoverParameters->Couplers[ CouplNr ].AllowedFlag
& ctrain_heating ) == ctrain_heating )
if( tmp->MoverParameters->Attach(
CouplNr, 2,
tmp->MoverParameters->Couplers[ CouplNr ].Connected,
( tmp->MoverParameters->Couplers[ CouplNr ].CouplingFlag | ctrain_heating ) ) ) {
// TODO: dedicated 'click' sound for connecting cable-type connections
play_sound( dsbCouplerAttach );
// one coupling type per key press
return;
}
}
}
@@ -3478,6 +3516,19 @@ bool TTrain::Update( double const Deltatime )
m_linebreakerstate = 0;
}
// NOTE: crude way to have the pantographs go back up if they're dropped due to insufficient pressure etc
// TODO: rework it into something more elegant, when redoing the whole consist/unit/cab etc arrangement
if( ( mvControlled->Battery )
|| ( mvControlled->ConverterFlag ) ) {
if( ( false == mvControlled->PantFrontUp )
&& ( ggPantFrontButton.GetValue() > 0.95 ) ) {
mvControlled->PantFront( true );
}
if( ( false == mvControlled->PantRearUp )
&& ( ggPantRearButton.GetValue() > 0.95 ) ) {
mvControlled->PantRear( true );
}
}
/*
// NOTE: disabled while switch state isn't preserved while moving between compartments
// check whether we should raise the pantographs, based on volume in pantograph tank
@@ -3502,15 +3553,14 @@ bool TTrain::Update( double const Deltatime )
tor = DynamicObject->GetTrack(); // McZapkie-180203
// McZapkie: predkosc wyswietlana na tachometrze brana jest z obrotow kol
float maxtacho = 3;
fTachoVelocity = Min0R(fabs(11.31 * mvControlled->WheelDiameter * mvControlled->nrot),
mvControlled->Vmax * 1.05);
fTachoVelocity = static_cast<float>( std::min( std::abs(11.31 * mvControlled->WheelDiameter * mvControlled->nrot), mvControlled->Vmax * 1.05) );
{ // skacze osobna zmienna
float ff = simulation::Time.data().wSecond; // skacze co sekunde - pol sekundy
// pomiar, pol sekundy ustawienie
if (ff != fTachoTimer) // jesli w tej sekundzie nie zmienial
{
if (fTachoVelocity > 1) // jedzie
fTachoVelocityJump = fTachoVelocity + (2 - Random(3) + Random(3)) * 0.5;
fTachoVelocityJump = fTachoVelocity + (2.0 - Random(3) + Random(3)) * 0.5;
else
fTachoVelocityJump = 0; // stoi
fTachoTimer = ff; // juz zmienil
@@ -3725,12 +3775,14 @@ bool TTrain::Update( double const Deltatime )
// przy dowolnym ustawieniu kierunkowego
// Ra: to już jest w T_MoverParameters::TractionForce(), ale zależy od
// kierunku
if (mvControlled->EngineType == ElectricSeriesMotor)
if (fabs(mvControlled->RunningTraction.TractionVoltage) <
0.5 *
mvControlled->EnginePowerSource
.MaxVoltage) // minimalne napięcie pobierać z FIZ?
mvControlled->MainSwitch(false);
if( mvControlled->EngineType == ElectricSeriesMotor ) {
if( std::max( mvControlled->GetTrainsetVoltage(), std::fabs( mvControlled->RunningTraction.TractionVoltage ) ) < 0.5 * mvControlled->EnginePowerSource.MaxVoltage ) {
// TODO: check whether it should affect entire consist for EMU
// TODO: check whether it should happen if there's power supplied alternatively through hvcouplers
// TODO: potentially move this to the mover module, as there isn't much reason to have this dependent on the operator presence
mvControlled->MainSwitch( false, false );
}
}
// hunter-091012: swiatlo
if (bCabLight == true)
@@ -3759,7 +3811,7 @@ bool TTrain::Update( double const Deltatime )
{
mvControlled->ConvOvldFlag = true;
if (mvControlled->TrainType != dt_EZT)
mvControlled->MainSwitch(false);
mvControlled->MainSwitch(false, mvControlled->TrainType == dt_EZT);
}
else if( fConverterTimer >= fConverterPrzekaznik ) {
// changed switch from always true to take into account state of the compressor switch
@@ -4702,74 +4754,20 @@ bool TTrain::Update( double const Deltatime )
ggManualBrake.UpdateValue(double(mvOccupied->ManualBrakePos));
ggManualBrake.Update();
}
if (ggBrakeProfileCtrl.SubModel)
{
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
ggBrakeProfileCtrl.UpdateValue(
double(mvOccupied->BrakeDelayFlag == 4 ? 2 : mvOccupied->BrakeDelayFlag - 1));
#endif
ggBrakeProfileCtrl.Update();
}
if (ggBrakeProfileG.SubModel)
{
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
ggBrakeProfileG.UpdateValue( double( mvOccupied->BrakeDelayFlag == bdelay_G ? 1 : 0 ) );
#endif
ggBrakeProfileG.Update();
}
if (ggBrakeProfileR.SubModel)
{
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
ggBrakeProfileR.UpdateValue( double( mvOccupied->BrakeDelayFlag == bdelay_R ? 1 : 0 ) );
#endif
ggBrakeProfileR.Update();
}
if (ggMaxCurrentCtrl.SubModel)
{
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
ggMaxCurrentCtrl.UpdateValue( double( mvControlled->Imax == mvControlled->ImaxHi ) );
#endif
ggMaxCurrentCtrl.Update();
}
ggBrakeProfileCtrl.Update();
ggBrakeProfileG.Update();
ggBrakeProfileR.Update();
ggMaxCurrentCtrl.Update();
// NBMX wrzesien 2003 - drzwi
if (ggDoorLeftButton.SubModel)
{
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
ggDoorLeftButton.PutValue( mvOccupied->DoorLeftOpened ? 1 : 0 );
#endif
ggDoorLeftButton.Update();
}
if (ggDoorRightButton.SubModel)
{
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
ggDoorRightButton.PutValue( mvOccupied->DoorRightOpened ? 1 : 0 );
#endif
ggDoorRightButton.Update();
}
if (ggDepartureSignalButton.SubModel)
{
// ggDepartureSignalButton.UpdateValue(double());
ggDepartureSignalButton.Update();
}
ggDoorLeftButton.Update();
ggDoorRightButton.Update();
ggDepartureSignalButton.Update();
// NBMX dzwignia sprezarki
if (ggCompressorButton.SubModel) // hunter-261211: poprawka
ggCompressorButton.Update();
if (ggMainButton.SubModel)
ggMainButton.Update();
if (ggRadioButton.SubModel)
{
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
ggRadioButton.PutValue( mvOccupied->Radio ? 1 : 0 );
#endif
ggRadioButton.Update();
}
if (ggConverterButton.SubModel)
ggConverterButton.Update();
if (ggConverterOffButton.SubModel)
ggConverterOffButton.Update();
ggCompressorButton.Update();
ggMainButton.Update();
ggRadioButton.Update();
ggConverterButton.Update();
ggConverterOffButton.Update();
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
if( ( ( DynamicObject->iLights[ 0 ] ) == 0 ) && ( ( DynamicObject->iLights[ 1 ] ) == 0 ) )
@@ -4918,64 +4916,18 @@ bool TTrain::Update( double const Deltatime )
ggLightsButton.PutValue(mvOccupied->LightsPos - 1);
ggLightsButton.Update();
}
if( ggDimHeadlightsButton.SubModel ) {
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
ggDimHeadlightsButton.PutValue( DynamicObject->DimHeadlights ? 1.0 : 0.0 );
#endif
ggDimHeadlightsButton.Update();
}
ggDimHeadlightsButton.Update();
//---------
// Winger 010304 - pantografy
// NOTE: shouldn't the pantograph updates check whether it's front or rear cabin?
if (ggPantFrontButton.SubModel ) {
ggPantFrontButton.Update();
}
if (ggPantRearButton.SubModel) {
ggPantRearButton.Update();
}
if (ggPantFrontButtonOff.SubModel) {
ggPantFrontButtonOff.Update();
}
ggPantFrontButton.Update();
ggPantRearButton.Update();
ggPantFrontButtonOff.Update();
ggTrainHeatingButton.Update();
ggSignallingButton.Update();
ggDoorSignallingButton.Update();
// Winger 020304 - ogrzewanie
//----------
// hunter-080812: poprawka na ogrzewanie w elektrykach - usuniete uzaleznienie od przetwornicy
if( ggTrainHeatingButton.SubModel )
{
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
if( mvControlled->Heating )
{
ggTrainHeatingButton.PutValue(1);
// if (mvControlled->ConverterFlag==true)
// btLampkaOgrzewanieSkladu.TurnOn();
}
else
{
ggTrainHeatingButton.PutValue(0);
// btLampkaOgrzewanieSkladu.TurnOff();
}
#endif
ggTrainHeatingButton.Update();
}
if (ggSignallingButton.SubModel != nullptr)
{
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
ggSignallingButton.PutValue( mvControlled->Signalling ? 1 : 0 );
#endif
ggSignallingButton.Update();
}
if (ggDoorSignallingButton.SubModel != nullptr)
{
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
ggDoorSignallingButton.PutValue( mvControlled->DoorSignalling ? 1 : 0 );
#endif
ggDoorSignallingButton.Update();
}
// if (ggDistCounter.SubModel)
//{//Ra 2014-07: licznik kilometrów
// ggDistCounter.PutValue(mvControlled->DistCounter);
// ggDistCounter.Update();
//}
if ((((mvControlled->EngineType == ElectricSeriesMotor) && (mvControlled->Mains == true) &&
(mvControlled->ConvOvldFlag == false)) ||
(mvControlled->ConverterFlag)) &&

View File

@@ -1820,24 +1820,48 @@ TWorld::Update_UI() {
uitextline2 +=
"; TC:"
+ to_string( tmp->MoverParameters->TotalCurrent, 0 );
#ifdef EU07_USE_OLD_HVCOUPLERS
uitextline2 +=
", HV0:"
+ to_string( tmp->MoverParameters->HVCouplers[ 0 ][ 1 ], 0 )
+ "@"
+ to_string( tmp->MoverParameters->HVCouplers[ 0 ][ 0 ], 0 );
", HV0: ("
+ to_string( tmp->MoverParameters->HVCouplers[ TMoverParameters::side::front ][ TMoverParameters::hvcoupler::outgoing ], 0 )
+ ")<-"
+ to_string( tmp->MoverParameters->HVCouplers[ TMoverParameters::side::front ][ TMoverParameters::hvcoupler::incoming ], 0 );
uitextline2 +=
", HV1:"
+ to_string( tmp->MoverParameters->HVCouplers[ 1 ][ 1 ], 0 )
+ "@"
+ to_string( tmp->MoverParameters->HVCouplers[ 1 ][ 0 ], 0 );
", HV1: ("
+ to_string( tmp->MoverParameters->HVCouplers[ TMoverParameters::side::rear ][ TMoverParameters::hvcoupler::outgoing ], 0 )
+ ")<-"
+ to_string( tmp->MoverParameters->HVCouplers[ TMoverParameters::side::rear ][ TMoverParameters::hvcoupler::incoming ], 0 );
#else
uitextline2 +=
", HV: "
+ to_string( tmp->MoverParameters->Couplers[ TMoverParameters::side::front ].power_high.incoming, 0 )
+ "->("
+ to_string( tmp->MoverParameters->Couplers[ TMoverParameters::side::front ].power_high.outgoing, 0 )
+ ")F" + (tmp->DirectionGet() ? "<<" : ">>") + "R("
+ to_string( tmp->MoverParameters->Couplers[ TMoverParameters::side::rear ].power_high.outgoing, 0 )
+ ")<-"
+ to_string( tmp->MoverParameters->Couplers[ TMoverParameters::side::rear ].power_high.incoming, 0 );
#endif
// equipment flags
uitextline3 = "";
uitextline3 += ( tmp->MoverParameters->Battery ? "B" : "b" );
uitextline3 += ( tmp->MoverParameters->Mains ? "M" : "m" );
uitextline3 += ( tmp->MoverParameters->PantRearUp ? ( tmp->MoverParameters->PantPressSwitchActive ? "O" : "o" ) : "." );;
uitextline3 += ( tmp->MoverParameters->PantFrontUp ? ( tmp->MoverParameters->PantPressSwitchActive ? "P" : "p" ) : "." );;
uitextline3 += ( tmp->MoverParameters->PantPressSwitchActive ? "!" : "." );
uitextline3 += ( tmp->MoverParameters->ConverterAllow ? ( tmp->MoverParameters->ConverterFlag ? "X" : "x" ) : "." );
uitextline3 += ( tmp->MoverParameters->ConvOvldFlag ? "!" : "." );
uitextline3 += ( tmp->MoverParameters->CompressorAllow ? ( tmp->MoverParameters->CompressorFlag ? "C" : "c" ) : "." );
uitextline3 += ( tmp->MoverParameters->CompressorGovernorLock ? "!" : "." );
uitextline3 =
"BP: " + to_string( tmp->MoverParameters->BrakePress, 2 )
uitextline3 +=
" BP: " + to_string( tmp->MoverParameters->BrakePress, 2 )
+ " (" + to_string( tmp->MoverParameters->BrakeStatus, 0 )
+ "), LBP: " + to_string( tmp->MoverParameters->LocBrakePress, 2 )
+ ", PP: " + to_string( tmp->MoverParameters->PipePress, 2 )
+ "/" + to_string( tmp->MoverParameters->ScndPipePress, 2 )
+ "/" + to_string( tmp->MoverParameters->EqvtPipePress, 2 )
+ ", MT: " + to_string( tmp->MoverParameters->CompressedVolume, 3 )
+ ", BVP: " + to_string( tmp->MoverParameters->Volume, 3 )
+ ", " + to_string( tmp->MoverParameters->CntrlPipePress, 3 )
+ ", " + to_string( tmp->MoverParameters->Hamulec->GetCRP(), 3 )