mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 15:39:19 +02:00
Merge branch 'tmj-dev' into milek-dev
This commit is contained in:
148
Driver.cpp
148
Driver.cpp
@@ -1390,6 +1390,12 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
fVelDes = v;
|
fVelDes = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if( ( true == TestFlag( sSpeedTable[ i ].iFlags, spEnd ) )
|
||||||
|
&& ( mvOccupied->CategoryFlag & 1 ) ) {
|
||||||
|
// if the railway track ends here set the velnext accordingly as well
|
||||||
|
// TODO: test this with turntables and such
|
||||||
|
fNext = 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (sSpeedTable[i].iFlags & spTrack) // jeśli tor
|
else if (sSpeedTable[i].iFlags & spTrack) // jeśli tor
|
||||||
{ // tor ogranicza prędkość, dopóki cały skład nie przejedzie,
|
{ // tor ogranicza prędkość, dopóki cały skład nie przejedzie,
|
||||||
@@ -1401,12 +1407,6 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
// ograniczenie aktualnej prędkości aż do wyjechania za ograniczenie
|
// ograniczenie aktualnej prędkości aż do wyjechania za ograniczenie
|
||||||
fVelDes = v;
|
fVelDes = v;
|
||||||
}
|
}
|
||||||
if( ( sSpeedTable[ i ].iFlags & spEnd )
|
|
||||||
&& ( mvOccupied->CategoryFlag & 1 ) ) {
|
|
||||||
// if the railway track ends here set the velnext accordingly as well
|
|
||||||
// TODO: test this with turntables and such
|
|
||||||
fNext = 0.0;
|
|
||||||
}
|
|
||||||
// if (v==0.0) fAcc=-0.9; //hamowanie jeśli stop
|
// if (v==0.0) fAcc=-0.9; //hamowanie jeśli stop
|
||||||
continue; // i tyle wystarczy
|
continue; // i tyle wystarczy
|
||||||
}
|
}
|
||||||
@@ -2131,7 +2131,10 @@ bool TController::CheckVehicles(TOrders user)
|
|||||||
// NOTE: don't set battery in the occupied vehicle, let the user/ai do it explicitly
|
// NOTE: don't set battery in the occupied vehicle, let the user/ai do it explicitly
|
||||||
p->MoverParameters->BatterySwitch( true );
|
p->MoverParameters->BatterySwitch( true );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// enable heating and converter in carriages with can be heated
|
// enable heating and converter in carriages with can be heated
|
||||||
|
// NOTE: don't touch the controlled vehicle, let the user/ai handle it explicitly
|
||||||
|
if( p->MoverParameters != mvControlling ) {
|
||||||
if( p->MoverParameters->HeatingPower > 0 ) {
|
if( p->MoverParameters->HeatingPower > 0 ) {
|
||||||
p->MoverParameters->HeatingAllow = true;
|
p->MoverParameters->HeatingAllow = true;
|
||||||
p->MoverParameters->ConverterSwitch( true, range_t::local );
|
p->MoverParameters->ConverterSwitch( true, range_t::local );
|
||||||
@@ -2266,6 +2269,12 @@ bool TController::CheckVehicles(TOrders user)
|
|||||||
// zmiana czoła przez manewry
|
// zmiana czoła przez manewry
|
||||||
iDrivigFlags &= ~movePushPull;
|
iDrivigFlags &= ~movePushPull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ( user == Connect )
|
||||||
|
|| ( user == Disconnect ) ) {
|
||||||
|
// HACK: force route table update on consist change, new consist length means distances to points of interest are now wrong
|
||||||
|
iTableDirection = 0;
|
||||||
|
}
|
||||||
} // blok wykonywany, gdy aktywnie prowadzi
|
} // blok wykonywany, gdy aktywnie prowadzi
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2454,7 +2463,7 @@ bool TController::PrepareEngine()
|
|||||||
mvOccupied->PantRear( true );
|
mvOccupied->PantRear( true );
|
||||||
if (mvControlling->PantPress < 4.2) {
|
if (mvControlling->PantPress < 4.2) {
|
||||||
// załączenie małej sprężarki
|
// załączenie małej sprężarki
|
||||||
if( mvControlling->TrainType != dt_EZT ) {
|
if( false == mvControlling->PantAutoValve ) {
|
||||||
// odłączenie zbiornika głównego, bo z nim nie da rady napompować
|
// odłączenie zbiornika głównego, bo z nim nie da rady napompować
|
||||||
mvControlling->bPantKurek3 = false;
|
mvControlling->bPantKurek3 = false;
|
||||||
}
|
}
|
||||||
@@ -2527,14 +2536,14 @@ bool TController::PrepareEngine()
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
OK = ( OrderDirectionChange( iDirection, mvOccupied ) == -1 );
|
OK = ( OrderDirectionChange( iDirection, mvOccupied ) == -1 );
|
||||||
mvOccupied->ConverterSwitch( true );
|
mvControlling->ConverterSwitch( true );
|
||||||
// w EN57 sprężarka w ra jest zasilana z silnikowego
|
// w EN57 sprężarka w ra jest zasilana z silnikowego
|
||||||
mvOccupied->CompressorSwitch( true );
|
mvControlling->CompressorSwitch( true );
|
||||||
// enable motor blowers
|
// enable motor blowers
|
||||||
mvOccupied->MotorBlowersSwitchOff( false, end::front );
|
mvControlling->MotorBlowersSwitchOff( false, end::front );
|
||||||
mvOccupied->MotorBlowersSwitch( true, end::front );
|
mvControlling->MotorBlowersSwitch( true, end::front );
|
||||||
mvOccupied->MotorBlowersSwitchOff( false, end::rear );
|
mvControlling->MotorBlowersSwitchOff( false, end::rear );
|
||||||
mvOccupied->MotorBlowersSwitch( true, end::rear );
|
mvControlling->MotorBlowersSwitch( true, end::rear );
|
||||||
// enable train brake if it's off
|
// enable train brake if it's off
|
||||||
if( mvOccupied->fBrakeCtrlPos == mvOccupied->Handle->GetPos( bh_NP ) ) {
|
if( mvOccupied->fBrakeCtrlPos == mvOccupied->Handle->GetPos( bh_NP ) ) {
|
||||||
mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) );
|
mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) );
|
||||||
@@ -2548,6 +2557,14 @@ bool TController::PrepareEngine()
|
|||||||
if( lookup != brakepositions.end() ) {
|
if( lookup != brakepositions.end() ) {
|
||||||
BrakeLevelSet( lookup->second ); // GBH
|
BrakeLevelSet( lookup->second ); // GBH
|
||||||
}
|
}
|
||||||
|
// enable train heating
|
||||||
|
// HACK: to account for su-45/-46 shortcomings diesel-powered engines only activate heating in cold conditions
|
||||||
|
// TODO: take instead into account presence of converters in attached cars, once said presence is possible to specify
|
||||||
|
mvControlling->HeatingAllow = (
|
||||||
|
( ( mvControlling->EngineType == TEngineType::DieselElectric )
|
||||||
|
|| ( mvControlling->EngineType == TEngineType::DieselEngine ) ) ?
|
||||||
|
( Global.AirTemperature < 10 ) :
|
||||||
|
true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2630,7 +2647,9 @@ bool TController::ReleaseEngine() {
|
|||||||
mvOccupied->OperateDoors( side::left, false );
|
mvOccupied->OperateDoors( side::left, false );
|
||||||
|
|
||||||
if( true == mvControlling->Mains ) {
|
if( true == mvControlling->Mains ) {
|
||||||
mvControlling->CompressorSwitch( false );
|
// heating
|
||||||
|
mvControlling->HeatingAllow = false;
|
||||||
|
// devices
|
||||||
mvControlling->ConverterSwitch( false );
|
mvControlling->ConverterSwitch( false );
|
||||||
// line breaker/engine
|
// line breaker/engine
|
||||||
OK = mvControlling->MainSwitch( false );
|
OK = mvControlling->MainSwitch( false );
|
||||||
@@ -3129,6 +3148,14 @@ bool TController::IncSpeed()
|
|||||||
{ // dla 2Ls150 można zmienić tryb pracy, jeśli jest w liniowym i nie daje rady (wymaga zerowania kierunku)
|
{ // dla 2Ls150 można zmienić tryb pracy, jeśli jest w liniowym i nie daje rady (wymaga zerowania kierunku)
|
||||||
// mvControlling->ShuntMode=(OrderList[OrderPos]&Shunt)||(fMass>224000.0);
|
// mvControlling->ShuntMode=(OrderList[OrderPos]&Shunt)||(fMass>224000.0);
|
||||||
}
|
}
|
||||||
|
if (mvControlling->EIMCtrlType > 0) {
|
||||||
|
if (true == Ready)
|
||||||
|
{
|
||||||
|
DizelPercentage = (mvControlling->Vel > mvControlling->dizel_minVelfullengage ? 100 : 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
if( true == Ready ) {
|
if( true == Ready ) {
|
||||||
if( ( mvControlling->Vel > mvControlling->dizel_minVelfullengage )
|
if( ( mvControlling->Vel > mvControlling->dizel_minVelfullengage )
|
||||||
&& ( mvControlling->RList[ mvControlling->MainCtrlPos ].Mn > 0 ) ) {
|
&& ( mvControlling->RList[ mvControlling->MainCtrlPos ].Mn > 0 ) ) {
|
||||||
@@ -3191,6 +3218,12 @@ bool TController::DecSpeed(bool force)
|
|||||||
mvControlling->DecMainCtrl(3 + 3 * floor(0.5 + fabs(AccDesired)));
|
mvControlling->DecMainCtrl(3 + 3 * floor(0.5 + fabs(AccDesired)));
|
||||||
break;
|
break;
|
||||||
case TEngineType::DieselEngine:
|
case TEngineType::DieselEngine:
|
||||||
|
if (mvControlling->EIMCtrlType > 0)
|
||||||
|
{
|
||||||
|
DizelPercentage = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ((mvControlling->Vel > mvControlling->dizel_minVelfullengage))
|
if ((mvControlling->Vel > mvControlling->dizel_minVelfullengage))
|
||||||
{
|
{
|
||||||
if (mvControlling->RList[mvControlling->MainCtrlPos].Mn > 0)
|
if (mvControlling->RList[mvControlling->MainCtrlPos].Mn > 0)
|
||||||
@@ -3514,6 +3547,64 @@ void TController::SetTimeControllers()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//5. Check Main Controller in Dizels
|
//5. Check Main Controller in Dizels
|
||||||
|
//5.1. Digital controller in DMUs with hydro
|
||||||
|
if ((mvControlling->EngineType == TEngineType::DieselEngine) && (mvControlling->EIMCtrlType == 3))
|
||||||
|
{
|
||||||
|
|
||||||
|
DizelPercentage_Speed = DizelPercentage; //wstepnie procenty
|
||||||
|
auto MinVel{ std::min(mvControlling->hydro_TC_LockupSpeed, mvControlling->Vmax / 6) }; //minimal velocity
|
||||||
|
if (VelDesired > MinVel) //more power for faster ride
|
||||||
|
{
|
||||||
|
auto const Factor{ 10 * (mvControlling->Vmax) / (mvControlling->Vmax + 3 * mvControlling->Vel) };
|
||||||
|
auto DesiredPercentage{ clamp(
|
||||||
|
(VelDesired > mvControlling->Vel ?
|
||||||
|
(VelDesired - mvControlling->Vel) / Factor :
|
||||||
|
0),
|
||||||
|
0.0, 1.0) }; //correction for reaching desired velocity
|
||||||
|
if ((VelDesired < 0.5 * mvControlling->Vmax) //low velocity and reaching desired
|
||||||
|
&& (VelDesired - mvControlling->Vel < 10)) {
|
||||||
|
DesiredPercentage = std::min(DesiredPercentage, 0.75);
|
||||||
|
}
|
||||||
|
DizelPercentage_Speed = std::round(DesiredPercentage * DizelPercentage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DizelPercentage_Speed = std::min(DizelPercentage, mvControlling->Vel < 0.99 * VelDesired ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const DizelActualPercentage { int(100.4 * mvControlling->eimic_real) };
|
||||||
|
|
||||||
|
auto const PosInc { mvControlling->MainCtrlPosNo };
|
||||||
|
auto PosDec { 0 };
|
||||||
|
for( int i = PosInc; i >= 0; --i ) {
|
||||||
|
if( ( mvControlling->UniCtrlList[ i ].SetCtrlVal <= 0 )
|
||||||
|
&& ( mvControlling->UniCtrlList[ i ].SpeedDown > 0.01 ) ) {
|
||||||
|
PosDec = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( std::abs( DizelPercentage_Speed - DizelActualPercentage ) > ( DizelPercentage > 1 ? 0 : 0 ) ) {
|
||||||
|
|
||||||
|
if( ( PosDec > 0 )
|
||||||
|
&& ( ( DizelActualPercentage - DizelPercentage_Speed > 50 )
|
||||||
|
|| ( ( DizelPercentage_Speed == 0 )
|
||||||
|
&& ( DizelActualPercentage > 10 ) ) ) ) {
|
||||||
|
//one position earlier should be fast decreasing
|
||||||
|
PosDec -= 1;
|
||||||
|
}
|
||||||
|
auto const DesiredPos { (
|
||||||
|
DizelPercentage_Speed > DizelActualPercentage ?
|
||||||
|
PosInc :
|
||||||
|
PosDec ) };
|
||||||
|
while( mvControlling->MainCtrlPos > DesiredPos ) { mvControlling->DecMainCtrl( 1 ); }
|
||||||
|
while( mvControlling->MainCtrlPos < DesiredPos ) { mvControlling->IncMainCtrl( 1 ); }
|
||||||
|
}
|
||||||
|
if (BrakeCtrlPosition < 0.1) //jesli nie hamuje
|
||||||
|
mvOccupied->BrakeLevelSet(mvControlling->UniCtrlList[mvControlling->MainCtrlPos].mode); //zeby nie bruzdzilo machanie zespolonym
|
||||||
|
}
|
||||||
|
else
|
||||||
|
//5.2. Analog direct controller
|
||||||
if ((mvControlling->EngineType == TEngineType::DieselEngine)&&(mvControlling->Vmax>30))
|
if ((mvControlling->EngineType == TEngineType::DieselEngine)&&(mvControlling->Vmax>30))
|
||||||
{
|
{
|
||||||
int MaxPos = mvControlling->MainCtrlPosNo;
|
int MaxPos = mvControlling->MainCtrlPosNo;
|
||||||
@@ -3573,6 +3664,28 @@ void TController::CheckTimeControllers()
|
|||||||
mvOccupied->ScndCtrlPos = 2;
|
mvOccupied->ScndCtrlPos = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//5. Check Main Controller in Dizels
|
||||||
|
//5.1. Digital controller in DMUs with hydro
|
||||||
|
if ((mvControlling->EngineType == TEngineType::DieselEngine) && (mvControlling->EIMCtrlType == 3))
|
||||||
|
{
|
||||||
|
int DizelActualPercentage = 100.4 * mvControlling->eimic_real;
|
||||||
|
int NeutralPos = mvControlling->MainCtrlPosNo - 1; //przedostatnia powinna wstrzymywać - hipoteza robocza
|
||||||
|
for (int i = mvControlling->MainCtrlPosNo; i >= 0; i--)
|
||||||
|
if ((mvControlling->UniCtrlList[i].SetCtrlVal <= 0) && (mvControlling->UniCtrlList[i].SpeedDown < 0.01)) //niby zero, ale nie zmniejsza procentów
|
||||||
|
{
|
||||||
|
NeutralPos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (BrakeCtrlPosition < 0.1) //jesli nie hamuje
|
||||||
|
{
|
||||||
|
if ((DizelActualPercentage >= DizelPercentage_Speed) && (mvControlling->MainCtrlPos > NeutralPos))
|
||||||
|
while (mvControlling->MainCtrlPos > NeutralPos) mvControlling->DecMainCtrl(1);
|
||||||
|
if ((DizelActualPercentage <= DizelPercentage_Speed) && (mvControlling->MainCtrlPos < NeutralPos))
|
||||||
|
while (mvControlling->MainCtrlPos < NeutralPos) mvControlling->IncMainCtrl(1);
|
||||||
|
mvOccupied->BrakeLevelSet(mvControlling->UniCtrlList[mvControlling->MainCtrlPos].mode); //zeby nie bruzdzilo machanie zespolonym
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// otwieranie/zamykanie drzwi w składzie albo (tylko AI) EZT
|
// otwieranie/zamykanie drzwi w składzie albo (tylko AI) EZT
|
||||||
@@ -4704,7 +4817,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
iCoupler = 0; // dalsza jazda manewrowa już bez łączenia
|
iCoupler = 0; // dalsza jazda manewrowa już bez łączenia
|
||||||
iDrivigFlags &= ~moveConnect; // zdjęcie flagi doczepiania
|
iDrivigFlags &= ~moveConnect; // zdjęcie flagi doczepiania
|
||||||
SetVelocity( 0, 0, stopJoin ); // wyłączyć przyspieszanie
|
SetVelocity( 0, 0, stopJoin ); // wyłączyć przyspieszanie
|
||||||
CheckVehicles(); // sprawdzić światła nowego składu
|
CheckVehicles( Connect ); // sprawdzić światła nowego składu
|
||||||
JumpToNextOrder(); // wykonanie następnej komendy
|
JumpToNextOrder(); // wykonanie następnej komendy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5071,6 +5184,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
// tylko jeśli odepnie
|
// tylko jeśli odepnie
|
||||||
WriteLog( mvOccupied->Name + " odczepiony." );
|
WriteLog( mvOccupied->Name + " odczepiony." );
|
||||||
iVehicleCount = -2;
|
iVehicleCount = -2;
|
||||||
|
CheckVehicles( Disconnect ); // update trainset state
|
||||||
} // a jak nie, to dociskać dalej
|
} // a jak nie, to dociskać dalej
|
||||||
}
|
}
|
||||||
if ((mvOccupied->Vel < 0.01) && !(iDrivigFlags & movePress))
|
if ((mvOccupied->Vel < 0.01) && !(iDrivigFlags & movePress))
|
||||||
@@ -5078,6 +5192,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
// za radą yB ustawiamy pozycję 3 kranu (ruszanie kranem w innych miejscach
|
// za radą yB ustawiamy pozycję 3 kranu (ruszanie kranem w innych miejscach
|
||||||
// powino zostać wyłączone)
|
// powino zostać wyłączone)
|
||||||
// WriteLog("Zahamowanie składu");
|
// WriteLog("Zahamowanie składu");
|
||||||
|
AccDesired = std::min( AccDesired, -0.9 ); // HACK: make sure the ai doesn't try to release the brakes to accelerate
|
||||||
if( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) {
|
if( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) {
|
||||||
mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_EPB ) );
|
mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_EPB ) );
|
||||||
}
|
}
|
||||||
@@ -5325,7 +5440,8 @@ TController::UpdateSituation(double dt) {
|
|||||||
exchangetime = std::max( exchangetime, vehicle->LoadExchangeTime() );
|
exchangetime = std::max( exchangetime, vehicle->LoadExchangeTime() );
|
||||||
vehicle = vehicle->Next();
|
vehicle = vehicle->Next();
|
||||||
}
|
}
|
||||||
if( exchangetime > 0 ) {
|
if( ( exchangetime > 0 )
|
||||||
|
|| ( mvOccupied->Vel > 2.0 ) ) { // HACK: force timer reset if the load exchange is cancelled due to departure
|
||||||
WaitingSet( exchangetime );
|
WaitingSet( exchangetime );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
Driver.h
2
Driver.h
@@ -256,6 +256,8 @@ public:
|
|||||||
int iOverheadZero = 0; // suma bitowa jezdy bezprądowej, bity ustawiane przez pojazdy z podniesionymi pantografami
|
int iOverheadZero = 0; // suma bitowa jezdy bezprądowej, bity ustawiane przez pojazdy z podniesionymi pantografami
|
||||||
int iOverheadDown = 0; // suma bitowa opuszczenia pantografów, bity ustawiane przez pojazdy z podniesionymi pantografami
|
int iOverheadDown = 0; // suma bitowa opuszczenia pantografów, bity ustawiane przez pojazdy z podniesionymi pantografami
|
||||||
double BrakeCtrlPosition = 0.0; // intermediate position of main brake controller
|
double BrakeCtrlPosition = 0.0; // intermediate position of main brake controller
|
||||||
|
int DizelPercentage = 0; // oczekiwane procenty jazdy/hamowania szynobusem
|
||||||
|
int DizelPercentage_Speed = 0; // oczekiwane procenty jazdy/hamowania szynobusem w związku z osiąganiem VelDesired
|
||||||
private:
|
private:
|
||||||
bool Psyche = false;
|
bool Psyche = false;
|
||||||
int HelperState = 0; //stan pomocnika maszynisty
|
int HelperState = 0; //stan pomocnika maszynisty
|
||||||
|
|||||||
31
DynObj.cpp
31
DynObj.cpp
@@ -2703,10 +2703,11 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
if (v == 0.0) {
|
if (v == 0.0) {
|
||||||
v = MoverParameters->PantFrontVolt;
|
v = MoverParameters->PantFrontVolt;
|
||||||
if( v == 0.0 ) {
|
if( v == 0.0 ) {
|
||||||
if( MoverParameters->TrainType & ( dt_EZT | dt_ET40 | dt_ET41 | dt_ET42 ) ) {
|
// if( MoverParameters->TrainType & ( dt_EZT | dt_ET40 | dt_ET41 | dt_ET42 ) ) {
|
||||||
// dwuczłony mogą mieć sprzęg WN
|
// dwuczłony mogą mieć sprzęg WN
|
||||||
|
// NOTE: condition disabled, other vehicles types can have power cables as well
|
||||||
v = MoverParameters->GetTrainsetVoltage(); // ostatnia szansa
|
v = MoverParameters->GetTrainsetVoltage(); // ostatnia szansa
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (v != 0.0)
|
if (v != 0.0)
|
||||||
@@ -2759,6 +2760,13 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
if (Mechanik)
|
if (Mechanik)
|
||||||
{ // Ra 2F3F: do Driver.cpp to przenieść?
|
{ // Ra 2F3F: do Driver.cpp to przenieść?
|
||||||
MoverParameters->EqvtPipePress = GetEPP(); // srednie cisnienie w PG
|
MoverParameters->EqvtPipePress = GetEPP(); // srednie cisnienie w PG
|
||||||
|
if ((Mechanik->Primary())
|
||||||
|
&& (MoverParameters->EngineType == TEngineType::DieselEngine)
|
||||||
|
&& (MoverParameters->EIMCtrlType > 0)) {
|
||||||
|
MoverParameters->CheckEIMIC(dt1);
|
||||||
|
MoverParameters->eimic_real = MoverParameters->eimic;
|
||||||
|
MoverParameters->SendCtrlToNext("EIMIC", MoverParameters->eimic, MoverParameters->CabNo);
|
||||||
|
}
|
||||||
if( ( Mechanik->Primary() )
|
if( ( Mechanik->Primary() )
|
||||||
&& ( MoverParameters->EngineType == TEngineType::ElectricInductionMotor ) ) {
|
&& ( MoverParameters->EngineType == TEngineType::ElectricInductionMotor ) ) {
|
||||||
// jesli glowny i z asynchronami, to niech steruje hamulcem i napedem lacznie dla calego pociagu/ezt
|
// jesli glowny i z asynchronami, to niech steruje hamulcem i napedem lacznie dla calego pociagu/ezt
|
||||||
@@ -5772,23 +5780,28 @@ TDynamicObject::LoadMMediaFile_mdload( std::string const &Name ) const {
|
|||||||
TModel3d *loadmodel { nullptr };
|
TModel3d *loadmodel { nullptr };
|
||||||
|
|
||||||
// check if we don't have model override for this load type
|
// check if we don't have model override for this load type
|
||||||
|
{
|
||||||
auto const lookup { LoadModelOverrides.find( Name ) };
|
auto const lookup { LoadModelOverrides.find( Name ) };
|
||||||
if( lookup != LoadModelOverrides.end() ) {
|
if( lookup != LoadModelOverrides.end() ) {
|
||||||
loadmodel = TModelsManager::GetModel( asBaseDir + lookup->second, true );
|
loadmodel = TModelsManager::GetModel( asBaseDir + lookup->second, true );
|
||||||
// if the override was succesfully loaded call it a day
|
// if the override was succesfully loaded call it a day
|
||||||
if( loadmodel != nullptr ) { return loadmodel; }
|
if( loadmodel != nullptr ) { return loadmodel; }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// regular routine if there's no override or it couldn't be loaded
|
// regular routine if there's no override or it couldn't be loaded
|
||||||
// try first specialized version of the load model, vehiclename_loadname
|
// try first specialized version of the load model, vehiclename_loadname
|
||||||
|
{
|
||||||
auto const specializedloadfilename { asBaseDir + MoverParameters->TypeName + "_" + Name };
|
auto const specializedloadfilename { asBaseDir + MoverParameters->TypeName + "_" + Name };
|
||||||
if( ( true == FileExists( specializedloadfilename + ".e3d" ) )
|
loadmodel = TModelsManager::GetModel( specializedloadfilename, true, false );
|
||||||
|| ( true == FileExists( specializedloadfilename + ".t3d" ) ) ) {
|
if( loadmodel != nullptr ) { return loadmodel; }
|
||||||
loadmodel = TModelsManager::GetModel( specializedloadfilename, true );
|
|
||||||
}
|
}
|
||||||
if( loadmodel == nullptr ) {
|
// try generic version of the load model next, loadname
|
||||||
// if this fails, try generic load model
|
{
|
||||||
loadmodel = TModelsManager::GetModel( asBaseDir + Name, true );
|
auto const genericloadfilename { asBaseDir + Name };
|
||||||
|
loadmodel = TModelsManager::GetModel( genericloadfilename, true, false );
|
||||||
|
if( loadmodel != nullptr ) { return loadmodel; }
|
||||||
}
|
}
|
||||||
|
// if we're still here, give up
|
||||||
return loadmodel;
|
return loadmodel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6630,7 +6643,7 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
|
|||||||
// youBy - przenioslem, bo diesel tez moze miec turbo
|
// youBy - przenioslem, bo diesel tez moze miec turbo
|
||||||
if( Vehicle.TurboTest > 0 ) {
|
if( Vehicle.TurboTest > 0 ) {
|
||||||
// udawanie turbo:
|
// udawanie turbo:
|
||||||
auto const pitch_diesel { Vehicle.EngineType == TEngineType::DieselEngine ? Vehicle.enrot / Vehicle.dizel_nmax : 0 };
|
auto const pitch_diesel { Vehicle.EngineType == TEngineType::DieselEngine ? Vehicle.enrot / Vehicle.dizel_nmax : 1 };
|
||||||
auto const goalpitch { std::max( 0.025, ( engine_volume * pitch_diesel + engine_turbo.m_frequencyoffset ) * engine_turbo.m_frequencyfactor ) };
|
auto const goalpitch { std::max( 0.025, ( engine_volume * pitch_diesel + engine_turbo.m_frequencyoffset ) * engine_turbo.m_frequencyfactor ) };
|
||||||
auto const goalvolume { (
|
auto const goalvolume { (
|
||||||
( ( Vehicle.MainCtrlPos >= Vehicle.TurboTest ) && ( Vehicle.enrot > 0.1 ) ) ?
|
( ( Vehicle.MainCtrlPos >= Vehicle.TurboTest ) && ( Vehicle.enrot > 0.1 ) ) ?
|
||||||
|
|||||||
30
EvLaunch.cpp
30
EvLaunch.cpp
@@ -58,12 +58,25 @@ bool TEventLauncher::Load(cParser *parser)
|
|||||||
dRadius *= dRadius; // do kwadratu, pod warunkiem, że nie jest ujemne
|
dRadius *= dRadius; // do kwadratu, pod warunkiem, że nie jest ujemne
|
||||||
parser->getTokens(); // klawisz sterujący
|
parser->getTokens(); // klawisz sterujący
|
||||||
*parser >> token;
|
*parser >> token;
|
||||||
if (token != "none")
|
if (token != "none") {
|
||||||
{
|
|
||||||
if( token.size() == 1 )
|
if( token.size() == 1 ) {
|
||||||
|
// single char, assigned activation key
|
||||||
iKey = vk_to_glfw_key( token[ 0 ] );
|
iKey = vk_to_glfw_key( token[ 0 ] );
|
||||||
else
|
}
|
||||||
iKey = vk_to_glfw_key(stol_def( token, 0 )); // a jak więcej, to jakby numer klawisza jest
|
else {
|
||||||
|
// this launcher may be activated by radio message
|
||||||
|
std::map<std::string, int> messages {
|
||||||
|
{ "radio_call1", radio_message::call1 },
|
||||||
|
{ "radio_call3", radio_message::call3 }
|
||||||
|
};
|
||||||
|
auto lookup = messages.find( token );
|
||||||
|
iKey = (
|
||||||
|
lookup != messages.end() ?
|
||||||
|
lookup->second :
|
||||||
|
// a jak więcej, to jakby numer klawisza jest
|
||||||
|
vk_to_glfw_key( stol_def( token, 0 ) ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
*parser >> DeltaTime;
|
*parser >> DeltaTime;
|
||||||
@@ -141,7 +154,7 @@ bool TEventLauncher::check_activation() {
|
|||||||
|
|
||||||
auto bCond { false };
|
auto bCond { false };
|
||||||
|
|
||||||
if( iKey != 0 ) {
|
if( iKey > 0 ) {
|
||||||
if( iKey > 255 ) {
|
if( iKey > 255 ) {
|
||||||
// key and modifier
|
// key and modifier
|
||||||
auto const modifier = ( iKey & 0xff00 ) >> 8;
|
auto const modifier = ( iKey & 0xff00 ) >> 8;
|
||||||
@@ -205,6 +218,11 @@ bool TEventLauncher::IsGlobal() const {
|
|||||||
&& ( dRadius < 0.0 ) ); // bez ograniczenia zasięgu
|
&& ( dRadius < 0.0 ) ); // bez ograniczenia zasięgu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TEventLauncher::IsRadioActivated() const {
|
||||||
|
|
||||||
|
return ( iKey < 0 );
|
||||||
|
}
|
||||||
|
|
||||||
// radius() subclass details, calculates node's bounding radius
|
// radius() subclass details, calculates node's bounding radius
|
||||||
float
|
float
|
||||||
TEventLauncher::radius_() {
|
TEventLauncher::radius_() {
|
||||||
|
|||||||
10
EvLaunch.h
10
EvLaunch.h
@@ -14,6 +14,12 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Classes.h"
|
#include "Classes.h"
|
||||||
#include "scenenode.h"
|
#include "scenenode.h"
|
||||||
|
|
||||||
|
// radio-transmitted event launch messages
|
||||||
|
enum radio_message {
|
||||||
|
call3 = -3,
|
||||||
|
call1 = -1
|
||||||
|
};
|
||||||
|
|
||||||
class TEventLauncher : public scene::basic_node {
|
class TEventLauncher : public scene::basic_node {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -27,7 +33,11 @@ public:
|
|||||||
bool check_activation();
|
bool check_activation();
|
||||||
// checks conditions associated with the event. returns: true if the conditions are met
|
// checks conditions associated with the event. returns: true if the conditions are met
|
||||||
bool check_conditions();
|
bool check_conditions();
|
||||||
|
inline
|
||||||
|
auto key() const {
|
||||||
|
return iKey; }
|
||||||
bool IsGlobal() const;
|
bool IsGlobal() const;
|
||||||
|
bool IsRadioActivated() const;
|
||||||
// members
|
// members
|
||||||
std::string asEvent1Name;
|
std::string asEvent1Name;
|
||||||
std::string asEvent2Name;
|
std::string asEvent2Name;
|
||||||
|
|||||||
37
Event.cpp
37
Event.cpp
@@ -1034,7 +1034,7 @@ logvalues_event::export_as_text_( std::ostream &Output ) const {
|
|||||||
void
|
void
|
||||||
multi_event::init() {
|
multi_event::init() {
|
||||||
|
|
||||||
auto const conditiontchecksmemcell { m_conditions.flags & ( flags::text | flags::value_1 | flags::value_2 ) };
|
auto const conditiontchecksmemcell { ( m_conditions.flags & ( flags::text | flags::value_1 | flags::value_2 ) ) != 0 };
|
||||||
// not all multi-events have memory cell checks, for the ones which don't we can keep quiet about it
|
// not all multi-events have memory cell checks, for the ones which don't we can keep quiet about it
|
||||||
init_targets( simulation::Memory, "memory cell", conditiontchecksmemcell );
|
init_targets( simulation::Memory, "memory cell", conditiontchecksmemcell );
|
||||||
if( m_ignored ) {
|
if( m_ignored ) {
|
||||||
@@ -1974,6 +1974,22 @@ event_manager::queue( TEventLauncher *Launcher ) {
|
|||||||
m_launcherqueue.emplace_back( Launcher );
|
m_launcherqueue.emplace_back( Launcher );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inserts in the event query events assigned to event launchers capable of receiving specified radio message sent from specified location
|
||||||
|
void
|
||||||
|
event_manager::queue_receivers( radio_message const Message, glm::dvec3 const &Location ) {
|
||||||
|
|
||||||
|
for( auto *launcher : m_radiodrivenlaunchers.sequence() ) {
|
||||||
|
if( ( launcher->key() == Message )
|
||||||
|
&& ( ( launcher->dRadius < 0 )
|
||||||
|
|| ( glm::length2( launcher->location() - Location ) < launcher->dRadius ) )
|
||||||
|
&& ( true == launcher->check_conditions() ) ) {
|
||||||
|
// NOTE: only execution of event1 is supported for radio messages
|
||||||
|
// TBD, TODO: consider ability/way to execute event2
|
||||||
|
simulation::Events.AddToQuery( launcher->Event1, nullptr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// legacy method, updates event queues
|
// legacy method, updates event queues
|
||||||
void
|
void
|
||||||
event_manager::update() {
|
event_manager::update() {
|
||||||
@@ -2177,7 +2193,13 @@ event_manager::InitEvents() {
|
|||||||
void
|
void
|
||||||
event_manager::InitLaunchers() {
|
event_manager::InitLaunchers() {
|
||||||
|
|
||||||
for( auto *launcher : m_launchers.sequence() ) {
|
std::vector<basic_table<TEventLauncher> *> launchertables {
|
||||||
|
&m_inputdrivenlaunchers,
|
||||||
|
&m_radiodrivenlaunchers
|
||||||
|
};
|
||||||
|
|
||||||
|
for( auto *launchertable : launchertables ) {
|
||||||
|
for( auto *launcher : launchertable->sequence() ) {
|
||||||
|
|
||||||
if( launcher->iCheckMask != 0 ) {
|
if( launcher->iCheckMask != 0 ) {
|
||||||
if( launcher->asMemCellName != "none" ) {
|
if( launcher->asMemCellName != "none" ) {
|
||||||
@@ -2207,6 +2229,7 @@ event_manager::InitLaunchers() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// sends basic content of the class in legacy (text) format to provided stream
|
// sends basic content of the class in legacy (text) format to provided stream
|
||||||
void
|
void
|
||||||
@@ -2218,8 +2241,14 @@ event_manager::export_as_text( std::ostream &Output ) const {
|
|||||||
event->export_as_text( Output );
|
event->export_as_text( Output );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Output << "// event launchers\n";
|
Output << "// event launchers, basic\n";
|
||||||
for( auto const *launcher : m_launchers.sequence() ) {
|
for( auto const *launcher : m_inputdrivenlaunchers.sequence() ) {
|
||||||
|
if( launcher->group() == null_handle ) {
|
||||||
|
launcher->export_as_text( Output );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Output << "// event launchers, radio driven\n";
|
||||||
|
for( auto const *launcher : m_radiodrivenlaunchers.sequence() ) {
|
||||||
if( launcher->group() == null_handle ) {
|
if( launcher->group() == null_handle ) {
|
||||||
launcher->export_as_text( Output );
|
launcher->export_as_text( Output );
|
||||||
}
|
}
|
||||||
|
|||||||
11
Event.h
11
Event.h
@@ -576,6 +576,9 @@ public:
|
|||||||
// adds specified event launcher to the list of global launchers
|
// adds specified event launcher to the list of global launchers
|
||||||
void
|
void
|
||||||
queue( TEventLauncher *Launcher );
|
queue( TEventLauncher *Launcher );
|
||||||
|
// inserts in the event query events assigned to event launchers capable of receiving specified radio message sent from specified location
|
||||||
|
void
|
||||||
|
queue_receivers( radio_message const Message, glm::dvec3 const &Location );
|
||||||
// legacy method, updates event queues
|
// legacy method, updates event queues
|
||||||
void
|
void
|
||||||
update();
|
update();
|
||||||
@@ -586,7 +589,10 @@ public:
|
|||||||
inline
|
inline
|
||||||
bool
|
bool
|
||||||
insert( TEventLauncher *Launcher ) {
|
insert( TEventLauncher *Launcher ) {
|
||||||
return m_launchers.insert( Launcher ); }
|
return (
|
||||||
|
Launcher->IsRadioActivated() ?
|
||||||
|
m_radiodrivenlaunchers.insert( Launcher ) :
|
||||||
|
m_inputdrivenlaunchers.insert( Launcher ) ); }
|
||||||
// returns first event in the queue
|
// returns first event in the queue
|
||||||
inline
|
inline
|
||||||
basic_event *
|
basic_event *
|
||||||
@@ -626,7 +632,8 @@ private:
|
|||||||
basic_event *QueryRootEvent { nullptr };
|
basic_event *QueryRootEvent { nullptr };
|
||||||
basic_event *m_workevent { nullptr };
|
basic_event *m_workevent { nullptr };
|
||||||
event_map m_eventmap;
|
event_map m_eventmap;
|
||||||
basic_table<TEventLauncher> m_launchers;
|
basic_table<TEventLauncher> m_inputdrivenlaunchers;
|
||||||
|
basic_table<TEventLauncher> m_radiodrivenlaunchers;
|
||||||
eventlauncher_sequence m_launcherqueue;
|
eventlauncher_sequence m_launcherqueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ TGauge::Load_mapping( cParser &Input ) {
|
|||||||
m_type = (
|
m_type = (
|
||||||
gaugetype == "impulse" ? TGaugeType::push :
|
gaugetype == "impulse" ? TGaugeType::push :
|
||||||
gaugetype == "return" ? TGaugeType::push :
|
gaugetype == "return" ? TGaugeType::push :
|
||||||
|
gaugetype == "delayed" ? TGaugeType::push_delayed :
|
||||||
TGaugeType::toggle ); // default
|
TGaugeType::toggle ); // default
|
||||||
}
|
}
|
||||||
else if( key == "soundinc:" ) {
|
else if( key == "soundinc:" ) {
|
||||||
|
|||||||
3
Gauge.h
3
Gauge.h
@@ -23,7 +23,8 @@ enum class TGaugeAnimation {
|
|||||||
|
|
||||||
enum class TGaugeType {
|
enum class TGaugeType {
|
||||||
toggle,
|
toggle,
|
||||||
push
|
push,
|
||||||
|
push_delayed
|
||||||
};
|
};
|
||||||
|
|
||||||
// animowany wskaźnik, mogący przyjmować wiele stanów pośrednich
|
// animowany wskaźnik, mogący przyjmować wiele stanów pośrednich
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
Parser.getTokens( 1, false );
|
Parser.getTokens( 1, false );
|
||||||
Parser >> FieldOfView;
|
Parser >> FieldOfView;
|
||||||
// guard against incorrect values
|
// guard against incorrect values
|
||||||
FieldOfView = clamp( FieldOfView, 15.0f, 75.0f );
|
FieldOfView = clamp( FieldOfView, 10.0f, 75.0f );
|
||||||
}
|
}
|
||||||
else if (token == "width")
|
else if (token == "width")
|
||||||
{
|
{
|
||||||
@@ -370,6 +370,11 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
>> shadowtune.depth
|
>> shadowtune.depth
|
||||||
>> shadowtune.distance;
|
>> shadowtune.distance;
|
||||||
}
|
}
|
||||||
|
else if( token == "gfx.shadows.cab.range" ) {
|
||||||
|
// shadow render toggle
|
||||||
|
Parser.getTokens();
|
||||||
|
Parser >> RenderCabShadowsRange;
|
||||||
|
}
|
||||||
else if (token == "smoothtraction")
|
else if (token == "smoothtraction")
|
||||||
{
|
{
|
||||||
// podwójna jasność ambient
|
// podwójna jasność ambient
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ struct global_settings {
|
|||||||
bool ScaleSpecularValues{ true };
|
bool ScaleSpecularValues{ true };
|
||||||
bool BasicRenderer{ false };
|
bool BasicRenderer{ false };
|
||||||
bool RenderShadows{ true };
|
bool RenderShadows{ true };
|
||||||
|
int RenderCabShadowsRange{ 0 };
|
||||||
struct shadowtune_t {
|
struct shadowtune_t {
|
||||||
unsigned int map_size{ 2048 };
|
unsigned int map_size{ 2048 };
|
||||||
float width{ 250.f }; // no longer used
|
float width{ 250.f }; // no longer used
|
||||||
|
|||||||
@@ -387,7 +387,7 @@ struct TBrakePressure
|
|||||||
typedef std::map<int,TBrakePressure> TBrakePressureTable;
|
typedef std::map<int,TBrakePressure> TBrakePressureTable;
|
||||||
|
|
||||||
/*typy napedow*/
|
/*typy napedow*/
|
||||||
enum class TEngineType { None, Dumb, WheelsDriven, ElectricSeriesMotor, ElectricInductionMotor, DieselEngine, SteamEngine, DieselElectric };
|
enum class TEngineType { None, Dumb, WheelsDriven, ElectricSeriesMotor, ElectricInductionMotor, DieselEngine, SteamEngine, DieselElectric, Main };
|
||||||
/*postac dostarczanej energii*/
|
/*postac dostarczanej energii*/
|
||||||
enum class TPowerType { NoPower, BioPower, MechPower, ElectricPower, SteamPower };
|
enum class TPowerType { NoPower, BioPower, MechPower, ElectricPower, SteamPower };
|
||||||
/*rodzaj paliwa*/
|
/*rodzaj paliwa*/
|
||||||
@@ -440,10 +440,22 @@ struct TCurrentCollector {
|
|||||||
//}
|
//}
|
||||||
};
|
};
|
||||||
/*typy źródeł mocy*/
|
/*typy źródeł mocy*/
|
||||||
enum class TPowerSource { NotDefined, InternalSource, Transducer, Generator, Accumulator, CurrentCollector, PowerCable, Heater };
|
enum class TPowerSource { NotDefined, InternalSource, Transducer, Generator, Accumulator, CurrentCollector, PowerCable, Heater, Main };
|
||||||
|
|
||||||
|
struct engine_generator {
|
||||||
|
// ld inputs
|
||||||
|
double *engine_revolutions; // revs per second of the prime mover
|
||||||
|
// config
|
||||||
|
double revolutions_min; // min working revolutions rate, in revs per second
|
||||||
|
double revolutions_max; // max working revolutions rate, in revs per second
|
||||||
|
double voltage_min; // voltage generated at min working revolutions
|
||||||
|
double voltage_max; // voltage generated at max working revolutions
|
||||||
|
// ld outputs
|
||||||
|
double revolutions;
|
||||||
|
double voltage;
|
||||||
|
};
|
||||||
|
|
||||||
struct _mover__1
|
struct TAccumulator
|
||||||
{
|
{
|
||||||
double MaxCapacity;
|
double MaxCapacity;
|
||||||
TPowerSource RechargeSource;
|
TPowerSource RechargeSource;
|
||||||
@@ -453,7 +465,7 @@ struct _mover__1
|
|||||||
//}
|
//}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _mover__2
|
struct TPowerCable
|
||||||
{
|
{
|
||||||
TPowerType PowerTrans;
|
TPowerType PowerTrans;
|
||||||
double SteamPressure;
|
double SteamPressure;
|
||||||
@@ -463,12 +475,17 @@ struct _mover__2
|
|||||||
//}
|
//}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _mover__3
|
struct THeater
|
||||||
{
|
{
|
||||||
TGrateType Grate;
|
TGrateType Grate;
|
||||||
TBoilerType Boiler;
|
TBoilerType Boiler;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TTransducer {
|
||||||
|
// ld inputs
|
||||||
|
double InputVoltage;
|
||||||
|
};
|
||||||
|
|
||||||
/*parametry źródeł mocy*/
|
/*parametry źródeł mocy*/
|
||||||
struct TPowerParameters
|
struct TPowerParameters
|
||||||
{
|
{
|
||||||
@@ -480,11 +497,11 @@ struct TPowerParameters
|
|||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
_mover__3 RHeater;
|
THeater RHeater;
|
||||||
};
|
};
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
_mover__2 RPowerCable;
|
TPowerCable RPowerCable;
|
||||||
};
|
};
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@@ -492,15 +509,15 @@ struct TPowerParameters
|
|||||||
};
|
};
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
_mover__1 RAccumulator;
|
TAccumulator RAccumulator;
|
||||||
};
|
};
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
TEngineType GeneratorEngine;
|
engine_generator EngineGenerator;
|
||||||
};
|
};
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
double InputVoltage;
|
TTransducer Transducer;
|
||||||
};
|
};
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@@ -618,7 +635,8 @@ enum class TCouplerType { NoCoupler, Articulated, Bare, Chain, Screw, Automatic
|
|||||||
struct power_coupling {
|
struct power_coupling {
|
||||||
double current{ 0.0 };
|
double current{ 0.0 };
|
||||||
double voltage{ 0.0 };
|
double voltage{ 0.0 };
|
||||||
bool local{ false }; // whether the power comes from external or onboard source
|
bool is_local{ false }; // whether the power comes from external or onboard source
|
||||||
|
bool is_live{ false }; // whether the coupling with next vehicle is live
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TCoupling {
|
struct TCoupling {
|
||||||
@@ -1022,7 +1040,11 @@ public:
|
|||||||
/* dizel_auto_min, dizel_auto_max: real; {predkosc obrotowa przelaczania automatycznej skrzyni biegow*/
|
/* dizel_auto_min, dizel_auto_max: real; {predkosc obrotowa przelaczania automatycznej skrzyni biegow*/
|
||||||
double dizel_nmax_cutoff = 0.0; /*predkosc obrotowa zadzialania ogranicznika predkosci*/
|
double dizel_nmax_cutoff = 0.0; /*predkosc obrotowa zadzialania ogranicznika predkosci*/
|
||||||
double dizel_nmin = 0.0; /*najmniejsza dopuszczalna predkosc obrotowa*/
|
double dizel_nmin = 0.0; /*najmniejsza dopuszczalna predkosc obrotowa*/
|
||||||
|
double dizel_nmin_hdrive = 0.0; /*najmniejsza dopuszczalna predkosc obrotowa w czasie jazdy na hydro */
|
||||||
|
double dizel_nmin_hdrive_factor = 0.0; /*wspolczynnik wzrostu obrotow minimalnych hydro zaleznosci od zadanego procentu*/
|
||||||
|
double dizel_nmin_retarder = 0.0; /*obroty pracy podczas hamowania retarderem*/
|
||||||
double dizel_minVelfullengage = 0.0; /*najmniejsza predkosc przy jezdzie ze sprzeglem bez poslizgu*/
|
double dizel_minVelfullengage = 0.0; /*najmniejsza predkosc przy jezdzie ze sprzeglem bez poslizgu*/
|
||||||
|
double dizel_maxVelANS = 3.0; /*predkosc progowa rozlaczenia przetwornika momentu*/
|
||||||
double dizel_AIM = 1.0; /*moment bezwladnosci walu itp*/
|
double dizel_AIM = 1.0; /*moment bezwladnosci walu itp*/
|
||||||
double dizel_engageDia = 0.5; double dizel_engageMaxForce = 6000.0; double dizel_engagefriction = 0.5; /*parametry sprzegla*/
|
double dizel_engageDia = 0.5; double dizel_engageMaxForce = 6000.0; double dizel_engagefriction = 0.5; /*parametry sprzegla*/
|
||||||
double engagedownspeed = 0.9;
|
double engagedownspeed = 0.9;
|
||||||
@@ -1050,6 +1072,7 @@ public:
|
|||||||
double hydro_R_FillRateInc = 1.0; /*szybkosc napelniania sprzegla*/
|
double hydro_R_FillRateInc = 1.0; /*szybkosc napelniania sprzegla*/
|
||||||
double hydro_R_FillRateDec = 1.0; /*szybkosc oprozniania sprzegla*/
|
double hydro_R_FillRateDec = 1.0; /*szybkosc oprozniania sprzegla*/
|
||||||
double hydro_R_MinVel = 1.0; /*minimalna predkosc, przy ktorej retarder dziala*/
|
double hydro_R_MinVel = 1.0; /*minimalna predkosc, przy ktorej retarder dziala*/
|
||||||
|
double hydro_R_EngageVel = 1.0; /*minimalna predkosc hamowania, przy ktorej sprzeglo jest wciaz wlaczone*/
|
||||||
/*- dla lokomotyw spalinowo-elektrycznych -*/
|
/*- dla lokomotyw spalinowo-elektrycznych -*/
|
||||||
double AnPos = 0.0; // pozycja sterowania dokladnego (analogowego)
|
double AnPos = 0.0; // pozycja sterowania dokladnego (analogowego)
|
||||||
bool AnalogCtrl = false; //
|
bool AnalogCtrl = false; //
|
||||||
@@ -1081,10 +1104,10 @@ public:
|
|||||||
double MED_EPVC_Time = 7; // czas korekcji sily hamowania EP, gdy nie ma dostepnego ED
|
double MED_EPVC_Time = 7; // czas korekcji sily hamowania EP, gdy nie ma dostepnego ED
|
||||||
bool MED_Ncor = 0; // czy korekcja sily hamowania z uwzglednieniem nacisku
|
bool MED_Ncor = 0; // czy korekcja sily hamowania z uwzglednieniem nacisku
|
||||||
|
|
||||||
int DCEMUED_CC; //na którym sprzęgu sprawdzać działanie ED
|
int DCEMUED_CC { 0 }; //na którym sprzęgu sprawdzać działanie ED
|
||||||
double DCEMUED_EP_max_Vel; //maksymalna prędkość, przy której działa EP przy włączonym ED w jednostce (dla tocznych)
|
double DCEMUED_EP_max_Vel{ 0.0 }; //maksymalna prędkość, przy której działa EP przy włączonym ED w jednostce (dla tocznych)
|
||||||
double DCEMUED_EP_min_Im; //minimalny prąd, przy którym EP nie działa przy włączonym ED w członie (dla silnikowych)
|
double DCEMUED_EP_min_Im{ 0.0 }; //minimalny prąd, przy którym EP nie działa przy włączonym ED w członie (dla silnikowych)
|
||||||
double DCEMUED_EP_delay; //opóźnienie włączenia hamulca EP przy hamowaniu ED - zwłoka wstępna
|
double DCEMUED_EP_delay{ 0.0 }; //opóźnienie włączenia hamulca EP przy hamowaniu ED - zwłoka wstępna
|
||||||
|
|
||||||
/*-dla wagonow*/
|
/*-dla wagonow*/
|
||||||
struct load_attributes {
|
struct load_attributes {
|
||||||
@@ -1225,6 +1248,8 @@ public:
|
|||||||
|
|
||||||
/*-zmienne dla lokomotyw*/
|
/*-zmienne dla lokomotyw*/
|
||||||
bool Mains = false; /*polozenie glownego wylacznika*/
|
bool Mains = false; /*polozenie glownego wylacznika*/
|
||||||
|
double MainsInitTime{ 0.0 }; // config, initialization time (in seconds) of the main circuit after it receives power, before it can be closed
|
||||||
|
double MainsInitTimeCountdown{ 0.0 }; // current state of main circuit initialization, remaining time (in seconds) until it's ready
|
||||||
int MainCtrlPos = 0; /*polozenie glownego nastawnika*/
|
int MainCtrlPos = 0; /*polozenie glownego nastawnika*/
|
||||||
int ScndCtrlPos = 0; /*polozenie dodatkowego nastawnika*/
|
int ScndCtrlPos = 0; /*polozenie dodatkowego nastawnika*/
|
||||||
int LightsPos = 0;
|
int LightsPos = 0;
|
||||||
@@ -1290,6 +1315,7 @@ public:
|
|||||||
double dizel_engagedeltaomega = 0.0; /*roznica predkosci katowych tarcz sprzegla*/
|
double dizel_engagedeltaomega = 0.0; /*roznica predkosci katowych tarcz sprzegla*/
|
||||||
double dizel_n_old = 0.0; /*poredkosc na potrzeby obliczen sprzegiel*/
|
double dizel_n_old = 0.0; /*poredkosc na potrzeby obliczen sprzegiel*/
|
||||||
double dizel_Torque = 0.0; /*poredkosc na potrzeby obliczen sprzegiel*/
|
double dizel_Torque = 0.0; /*poredkosc na potrzeby obliczen sprzegiel*/
|
||||||
|
double dizel_nreg_min = 0.0; /*predkosc regulatora minimalna, zmienna w hydro*/
|
||||||
|
|
||||||
/* - zmienne dla przetowrnika momentu */
|
/* - zmienne dla przetowrnika momentu */
|
||||||
double hydro_TC_Fill = 0.0; /*napelnienie*/
|
double hydro_TC_Fill = 0.0; /*napelnienie*/
|
||||||
@@ -1370,6 +1396,7 @@ public:
|
|||||||
|
|
||||||
double fBrakeCtrlPos = -2.0; // płynna nastawa hamulca zespolonego
|
double fBrakeCtrlPos = -2.0; // płynna nastawa hamulca zespolonego
|
||||||
bool bPantKurek3 = true; // kurek trójdrogowy (pantografu): true=połączenie z ZG, false=połączenie z małą sprężarką // domyślnie zbiornik pantografu połączony jest ze zbiornikiem głównym
|
bool bPantKurek3 = true; // kurek trójdrogowy (pantografu): true=połączenie z ZG, false=połączenie z małą sprężarką // domyślnie zbiornik pantografu połączony jest ze zbiornikiem głównym
|
||||||
|
bool PantAutoValve { false }; // type of installed pantograph compressor valve
|
||||||
int iProblem = 0; // flagi problemów z taborem, aby AI nie musiało porównywać; 0=może jechać
|
int iProblem = 0; // flagi problemów z taborem, aby AI nie musiało porównywać; 0=może jechać
|
||||||
int iLights[2]; // bity zapalonych świateł tutaj, żeby dało się liczyć pobór prądu
|
int iLights[2]; // bity zapalonych świateł tutaj, żeby dało się liczyć pobór prądu
|
||||||
|
|
||||||
@@ -1503,6 +1530,8 @@ public:
|
|||||||
bool CompressorSwitch( bool State, range_t const Notify = range_t::consist );/*! wl/wyl sprezarki*/
|
bool CompressorSwitch( bool State, range_t const Notify = range_t::consist );/*! wl/wyl sprezarki*/
|
||||||
|
|
||||||
/*-funkcje typowe dla lokomotywy elektrycznej*/
|
/*-funkcje typowe dla lokomotywy elektrycznej*/
|
||||||
|
void MainsCheck( double const Deltatime );
|
||||||
|
void PowerCouplersCheck( double const Deltatime );
|
||||||
void ConverterCheck( double const Timestep ); // przetwornica
|
void ConverterCheck( double const Timestep ); // przetwornica
|
||||||
void HeatingCheck( double const Timestep );
|
void HeatingCheck( double const Timestep );
|
||||||
void WaterPumpCheck( double const Timestep );
|
void WaterPumpCheck( double const Timestep );
|
||||||
@@ -1543,8 +1572,9 @@ public:
|
|||||||
bool dizel_EngageSwitch(double state);
|
bool dizel_EngageSwitch(double state);
|
||||||
bool dizel_EngageChange(double dt);
|
bool dizel_EngageChange(double dt);
|
||||||
bool dizel_AutoGearCheck(void);
|
bool dizel_AutoGearCheck(void);
|
||||||
double dizel_fillcheck(int mcp);
|
double dizel_fillcheck(int mcp, double dt);
|
||||||
double dizel_Momentum(double dizel_fill, double n, double dt);
|
double dizel_Momentum(double dizel_fill, double n, double dt);
|
||||||
|
double dizel_MomentumRetarder(double n, double dt); // moment hamowania retardera
|
||||||
void dizel_HeatSet( float const Value );
|
void dizel_HeatSet( float const Value );
|
||||||
void dizel_Heat( double const dt );
|
void dizel_Heat( double const dt );
|
||||||
bool dizel_StartupCheck();
|
bool dizel_StartupCheck();
|
||||||
|
|||||||
@@ -673,7 +673,7 @@ void TMoverParameters::UpdatePantVolume(double dt)
|
|||||||
// Ra 2014-07: kurek trójdrogowy łączy spr.pom. z pantografami i wyłącznikiem ciśnieniowym WS
|
// 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ąć
|
// Ra 2014-07: zbiornika rozrządu nie pompuje się tu, tylko pantografy; potem można zamknąć
|
||||||
// WS i odpalić resztę
|
// WS i odpalić resztę
|
||||||
if ((TrainType == dt_EZT) ?
|
if (PantAutoValve ?
|
||||||
(PantPress < ScndPipePress) :
|
(PantPress < ScndPipePress) :
|
||||||
bPantKurek3) // kurek zamyka połączenie z ZG
|
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
|
||||||
@@ -1070,85 +1070,6 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
|||||||
const double Vepsilon = 1e-5;
|
const double Vepsilon = 1e-5;
|
||||||
const double Aepsilon = 1e-3; // ASBSpeed=0.8;
|
const double Aepsilon = 1e-3; // ASBSpeed=0.8;
|
||||||
|
|
||||||
// T_MoverParameters::ComputeMovement(dt, dt1, Shape, Track, ElectricTraction, NewLoc, NewRot);
|
|
||||||
// // najpierw kawalek z funkcji w pliku mover.pas
|
|
||||||
TotalCurrent = 0;
|
|
||||||
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 == end::front ? end::rear : end::front ) };
|
|
||||||
auto const liveconnection{
|
|
||||||
( Couplers[ side ].CouplingFlag & ctrain_power )
|
|
||||||
|| ( ( Couplers[ side ].CouplingFlag & ctrain_heating )
|
|
||||||
&& ( Couplers[ side ].Connected->Heating ) ) };
|
|
||||||
|
|
||||||
if( liveconnection ) {
|
|
||||||
auto const &connectedcoupler = Couplers[ side ].Connected->Couplers[ Couplers[ side ].ConnectedNr ];
|
|
||||||
Couplers[ oppositeside ].power_high.voltage =
|
|
||||||
std::max(
|
|
||||||
std::abs( hvc ),
|
|
||||||
connectedcoupler.power_high.voltage - Couplers[ side ].power_high.current * 0.02 );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Couplers[ oppositeside ].power_high.voltage = std::abs( hvc ) - Couplers[ side ].power_high.current * 0.02;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hvc = Couplers[ end::front ].power_high.voltage + Couplers[ end::rear ].power_high.voltage;
|
|
||||||
|
|
||||||
if( std::abs( PantFrontVolt ) + std::abs( PantRearVolt ) < 1.0 ) {
|
|
||||||
// bez napiecia...
|
|
||||||
if( hvc != 0.0 ) {
|
|
||||||
// ...ale jest cos na sprzegach:
|
|
||||||
// przekazywanie pradow
|
|
||||||
for( int side = 0; side < 2; ++side ) {
|
|
||||||
|
|
||||||
Couplers[ side ].power_high.local = false; // power, if any, will be from external source
|
|
||||||
|
|
||||||
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|
|
||||||
|| ( ( Couplers[ side ].CouplingFlag & ctrain_heating )
|
|
||||||
&& ( Couplers[ side ].Connected->Heating ) ) ) {
|
|
||||||
auto const &connectedcoupler =
|
|
||||||
Couplers[ side ].Connected->Couplers[
|
|
||||||
( Couplers[ side ].ConnectedNr == end::front ?
|
|
||||||
end::rear :
|
|
||||||
end::front ) ];
|
|
||||||
Couplers[ side ].power_high.current =
|
|
||||||
connectedcoupler.power_high.current
|
|
||||||
+ Itot * Couplers[ side ].power_high.voltage / hvc; // obciążenie rozkladane stosownie do napiec
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Couplers[ side ].power_high.current = Itot * Couplers[ side ].power_high.voltage / hvc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for( int side = 0; side < 2; ++side ) {
|
|
||||||
|
|
||||||
Couplers[ side ].power_high.local = true; // power is coming from local pantographs
|
|
||||||
|
|
||||||
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|
|
||||||
|| ( ( Couplers[ side ].CouplingFlag & ctrain_heating )
|
|
||||||
&& ( Couplers[ side ].Connected->Heating ) ) ) {
|
|
||||||
auto const &connectedcoupler =
|
|
||||||
Couplers[ side ].Connected->Couplers[
|
|
||||||
( Couplers[ side ].ConnectedNr == end::front ?
|
|
||||||
end::rear :
|
|
||||||
end::front ) ];
|
|
||||||
TotalCurrent += connectedcoupler.power_high.current;
|
|
||||||
Couplers[ side ].power_high.current = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TestFlag(DamageFlag, dtrain_out))
|
if (!TestFlag(DamageFlag, dtrain_out))
|
||||||
{ // Ra: to przepisywanie tu jest bez sensu
|
{ // Ra: to przepisywanie tu jest bez sensu
|
||||||
RunningShape = Shape;
|
RunningShape = Shape;
|
||||||
@@ -1388,10 +1309,11 @@ void TMoverParameters::compute_movement_( double const Deltatime ) {
|
|||||||
RunInternalCommand();
|
RunInternalCommand();
|
||||||
|
|
||||||
// automatyczny rozruch
|
// automatyczny rozruch
|
||||||
if (EngineType == TEngineType::ElectricSeriesMotor)
|
if( EngineType == TEngineType::ElectricSeriesMotor ) {
|
||||||
|
if( AutoRelayCheck() ) {
|
||||||
if (AutoRelayCheck())
|
|
||||||
SetFlag( SoundFlag, sound::relay );
|
SetFlag( SoundFlag, sound::relay );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( ( EngineType == TEngineType::DieselEngine )
|
if( ( EngineType == TEngineType::DieselEngine )
|
||||||
|| ( EngineType == TEngineType::DieselElectric ) ) {
|
|| ( EngineType == TEngineType::DieselElectric ) ) {
|
||||||
@@ -1399,6 +1321,12 @@ void TMoverParameters::compute_movement_( double const Deltatime ) {
|
|||||||
SetFlag( SoundFlag, sound::relay );
|
SetFlag( SoundFlag, sound::relay );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: gather and move current calculations to dedicated method
|
||||||
|
TotalCurrent = 0;
|
||||||
|
|
||||||
|
// main circuit
|
||||||
|
MainsCheck( Deltatime );
|
||||||
// traction motors
|
// traction motors
|
||||||
MotorBlowersCheck( Deltatime );
|
MotorBlowersCheck( Deltatime );
|
||||||
// uklady hamulcowe:
|
// uklady hamulcowe:
|
||||||
@@ -1436,6 +1364,145 @@ void TMoverParameters::compute_movement_( double const Deltatime ) {
|
|||||||
BrakeSlippingTimer += Deltatime;
|
BrakeSlippingTimer += Deltatime;
|
||||||
// automatic doors
|
// automatic doors
|
||||||
update_doors( Deltatime );
|
update_doors( Deltatime );
|
||||||
|
|
||||||
|
PowerCouplersCheck( Deltatime );
|
||||||
|
}
|
||||||
|
|
||||||
|
void TMoverParameters::MainsCheck( double const Deltatime ) {
|
||||||
|
|
||||||
|
// TODO: move other main circuit checks here
|
||||||
|
|
||||||
|
if( MainsInitTime == 0.0 ) { return; }
|
||||||
|
|
||||||
|
if( MainsInitTimeCountdown > 0.0 ) {
|
||||||
|
MainsInitTimeCountdown -= Deltatime;
|
||||||
|
}
|
||||||
|
// TBD, TODO: move voltage calculation to separate method and use also in power coupler state calculation?
|
||||||
|
auto localvoltage { 0.0 };
|
||||||
|
switch( EnginePowerSource.SourceType ) {
|
||||||
|
case TPowerSource::CurrentCollector: {
|
||||||
|
localvoltage =
|
||||||
|
std::max(
|
||||||
|
localvoltage,
|
||||||
|
std::max(
|
||||||
|
PantFrontVolt,
|
||||||
|
PantRearVolt ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( ( localvoltage == 0.0 )
|
||||||
|
&& ( GetTrainsetVoltage() == 0 ) ) {
|
||||||
|
MainsInitTimeCountdown = MainsInitTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TMoverParameters::PowerCouplersCheck( double const Deltatime ) {
|
||||||
|
// TODO: add support for other power sources
|
||||||
|
auto localvoltage { 0.0 };
|
||||||
|
// heating power sources
|
||||||
|
if( Heating ) {
|
||||||
|
switch( HeatingPowerSource.SourceType ) {
|
||||||
|
case TPowerSource::Generator: {
|
||||||
|
localvoltage = HeatingPowerSource.EngineGenerator.voltage - TotalCurrent * 0.02;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TPowerSource::Main: {
|
||||||
|
localvoltage = ( true == Mains ? Voltage : 0.0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// high voltage power sources
|
||||||
|
switch( EnginePowerSource.SourceType ) {
|
||||||
|
case TPowerSource::CurrentCollector: {
|
||||||
|
localvoltage =
|
||||||
|
std::max(
|
||||||
|
localvoltage,
|
||||||
|
std::max(
|
||||||
|
PantFrontVolt,
|
||||||
|
PantRearVolt ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const abslocalvoltage { std::abs( localvoltage ) };
|
||||||
|
auto const localpowersource { ( abslocalvoltage > 1.0 ) };
|
||||||
|
/*
|
||||||
|
auto const localpowersource { ( std::abs( PantFrontVolt ) + std::abs( PantRearVolt ) > 1.0 ) };
|
||||||
|
auto hvc = std::max( PantFrontVolt, PantRearVolt );
|
||||||
|
*/
|
||||||
|
// przekazywanie napiec
|
||||||
|
for( auto side = 0; side < 2; ++side ) {
|
||||||
|
|
||||||
|
auto &coupler { Couplers[ side ] };
|
||||||
|
// NOTE: in the loop we actually update the state of the coupler on the opposite end of the vehicle
|
||||||
|
auto &oppositecoupler { Couplers[ ( side == end::front ? end::rear : end::front ) ] };
|
||||||
|
auto const oppositehighvoltagecoupling { ( oppositecoupler.CouplingFlag & coupling::highvoltage ) != 0 };
|
||||||
|
auto const oppositeheatingcoupling { ( oppositecoupler.CouplingFlag & coupling::heating ) != 0 };
|
||||||
|
|
||||||
|
// start with base voltage
|
||||||
|
oppositecoupler.power_high.voltage = abslocalvoltage;
|
||||||
|
oppositecoupler.power_high.is_live = false;
|
||||||
|
oppositecoupler.power_high.is_local = localpowersource; // indicate power source
|
||||||
|
// draw from external source
|
||||||
|
if( coupler.Connected != nullptr ) {
|
||||||
|
auto const &connectedcoupler { coupler.Connected->Couplers[ coupler.ConnectedNr ] };
|
||||||
|
auto const connectedvoltage { (
|
||||||
|
connectedcoupler.power_high.is_live ?
|
||||||
|
connectedcoupler.power_high.voltage :
|
||||||
|
0.0 ) };
|
||||||
|
oppositecoupler.power_high.voltage = std::max(
|
||||||
|
oppositecoupler.power_high.voltage,
|
||||||
|
connectedvoltage - coupler.power_high.current * 0.02 );
|
||||||
|
oppositecoupler.power_high.is_live =
|
||||||
|
( connectedvoltage > 0.1 )
|
||||||
|
&& ( oppositehighvoltagecoupling || oppositeheatingcoupling );
|
||||||
|
}
|
||||||
|
// draw from local source
|
||||||
|
if( localpowersource ) {
|
||||||
|
oppositecoupler.power_high.voltage = std::max(
|
||||||
|
oppositecoupler.power_high.voltage,
|
||||||
|
abslocalvoltage - coupler.power_high.current * 0.02 );
|
||||||
|
oppositecoupler.power_high.is_live |=
|
||||||
|
( abslocalvoltage > 0.1 )
|
||||||
|
&& ( oppositehighvoltagecoupling || ( oppositeheatingcoupling && localpowersource && Heating ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// przekazywanie pradow
|
||||||
|
auto couplervoltage { Couplers[ end::front ].power_high.voltage + Couplers[ end::rear ].power_high.voltage };
|
||||||
|
|
||||||
|
for( auto side = 0; side < 2; ++side ) {
|
||||||
|
|
||||||
|
auto &coupler { Couplers[ side ] };
|
||||||
|
auto const &connectedothercoupler { coupler.Connected->Couplers[ ( coupler.ConnectedNr == end::front ? end::rear : end::front ) ] };
|
||||||
|
|
||||||
|
coupler.power_high.current = 0.0;
|
||||||
|
if( false == localpowersource ) {
|
||||||
|
// bez napiecia...
|
||||||
|
if( couplervoltage != 0.0 ) {
|
||||||
|
// ...ale jest cos na sprzegach:
|
||||||
|
coupler.power_high.current = ( Itot + TotalCurrent ) * coupler.power_high.voltage / couplervoltage; // obciążenie rozkladane stosownie do napiec
|
||||||
|
if( true == coupler.power_high.is_live ) {
|
||||||
|
coupler.power_high.current += connectedothercoupler.power_high.current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if( true == coupler.power_high.is_live ) {
|
||||||
|
TotalCurrent += connectedothercoupler.power_high.current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double TMoverParameters::ShowEngineRotation(int VehN)
|
double TMoverParameters::ShowEngineRotation(int VehN)
|
||||||
@@ -1492,12 +1559,70 @@ void TMoverParameters::ConverterCheck( double const Timestep ) {
|
|||||||
// heating system status check
|
// heating system status check
|
||||||
void TMoverParameters::HeatingCheck( double const Timestep ) {
|
void TMoverParameters::HeatingCheck( double const Timestep ) {
|
||||||
|
|
||||||
Heating = (
|
// update heating devices
|
||||||
( true == HeatingAllow )
|
// TBD, TODO: move this to a separate method?
|
||||||
// powered vehicles are generally required to activate their power source to provide heating
|
switch( HeatingPowerSource.SourceType ) {
|
||||||
// passive vehicles get a pass in this regard
|
case TPowerSource::Generator: {
|
||||||
&& ( ( Power < 0.1 )
|
if( ( HeatingPowerSource.EngineGenerator.engine_revolutions != nullptr )
|
||||||
|| ( true == Mains ) ) );
|
&& ( HeatingPowerSource.EngineGenerator.revolutions_max > 0 ) ) {
|
||||||
|
|
||||||
|
auto &generator { HeatingPowerSource.EngineGenerator };
|
||||||
|
// TBD, TODO: engine-generator transmission
|
||||||
|
generator.revolutions = *(generator.engine_revolutions);
|
||||||
|
|
||||||
|
auto const absrevolutions { std::abs( generator.revolutions ) };
|
||||||
|
generator.voltage = (
|
||||||
|
absrevolutions < generator.revolutions_min ? generator.voltage_min * absrevolutions / generator.revolutions_min :
|
||||||
|
// absrevolutions > generator.revolutions_max ? generator.voltage_max * absrevolutions / generator.revolutions_max :
|
||||||
|
interpolate(
|
||||||
|
generator.voltage_min, generator.voltage_max,
|
||||||
|
clamp(
|
||||||
|
( absrevolutions - generator.revolutions_min ) / ( generator.revolutions_max - generator.revolutions_min ),
|
||||||
|
0.0, 1.0 ) ) )
|
||||||
|
* sign( generator.revolutions );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// quick check first to avoid unnecessary calls...
|
||||||
|
if( false == HeatingAllow ) {
|
||||||
|
Heating = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// ...detailed check if we're still here
|
||||||
|
auto const heatingpowerthreshold { 0.1 };
|
||||||
|
// start with external power sources
|
||||||
|
auto voltage { 0.0 };
|
||||||
|
// then try internal ones
|
||||||
|
switch( HeatingPowerSource.SourceType ) {
|
||||||
|
case TPowerSource::Generator: {
|
||||||
|
voltage = HeatingPowerSource.EngineGenerator.voltage;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TPowerSource::PowerCable: {
|
||||||
|
if( HeatingPowerSource.PowerType == TPowerType::ElectricPower ) {
|
||||||
|
voltage = GetTrainsetVoltage();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TPowerSource::Main: {
|
||||||
|
voltage = ( true == Mains ? Voltage : 0.0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Heating = ( std::abs( voltage ) > heatingpowerthreshold );
|
||||||
|
|
||||||
|
if( Heating ) {
|
||||||
|
TotalCurrent += 1000 * HeatingPower / voltage; // heater power cost presumably specified in kilowatts
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// water pump status check
|
// water pump status check
|
||||||
@@ -2765,6 +2890,7 @@ void TMoverParameters::MainSwitch_( bool const State ) {
|
|||||||
if( ( false == State )
|
if( ( false == State )
|
||||||
|| ( ( ( ScndCtrlPos == 0 ) || ( EngineType == TEngineType::ElectricInductionMotor ) )
|
|| ( ( ( ScndCtrlPos == 0 ) || ( EngineType == TEngineType::ElectricInductionMotor ) )
|
||||||
&& ( ( ConvOvldFlag == false ) || ( TrainType == dt_EZT ) )
|
&& ( ( ConvOvldFlag == false ) || ( TrainType == dt_EZT ) )
|
||||||
|
&& ( MainsInitTimeCountdown <= 0.0 )
|
||||||
&& ( true == NoVoltRelay )
|
&& ( true == NoVoltRelay )
|
||||||
&& ( true == OvervoltageRelay )
|
&& ( true == OvervoltageRelay )
|
||||||
&& ( LastSwitchingTime > CtrlDelay )
|
&& ( LastSwitchingTime > CtrlDelay )
|
||||||
@@ -3892,7 +4018,6 @@ void TMoverParameters::ComputeConstans(void)
|
|||||||
double BearingF, RollF, HideModifier;
|
double BearingF, RollF, HideModifier;
|
||||||
double Curvature; // Ra 2014-07: odwrotność promienia
|
double Curvature; // Ra 2014-07: odwrotność promienia
|
||||||
|
|
||||||
TotalCurrent = 0; // Ra 2014-04: tu zerowanie, aby EZT mogło pobierać prąd innemu członowi
|
|
||||||
TotalMass = ComputeMass();
|
TotalMass = ComputeMass();
|
||||||
TotalMassxg = TotalMass * g; // TotalMass*g
|
TotalMassxg = TotalMass * g; // TotalMass*g
|
||||||
BearingF = 2.0 * (DamageFlag && dtrain_bearing);
|
BearingF = 2.0 * (DamageFlag && dtrain_bearing);
|
||||||
@@ -4031,6 +4156,7 @@ void TMoverParameters::ComputeTotalForce(double dt) {
|
|||||||
else
|
else
|
||||||
Voltage = RunningTraction.TractionVoltage * DirAbsolute; // ActiveDir*CabNo;
|
Voltage = RunningTraction.TractionVoltage * DirAbsolute; // ActiveDir*CabNo;
|
||||||
} // bo nie dzialalo
|
} // bo nie dzialalo
|
||||||
|
// TODO: clean up this elseif to match changes in power coupling code
|
||||||
else if( ( EngineType == TEngineType::ElectricInductionMotor )
|
else if( ( EngineType == TEngineType::ElectricInductionMotor )
|
||||||
|| ( ( ( Couplers[ end::front ].CouplingFlag & ctrain_power ) == ctrain_power )
|
|| ( ( ( Couplers[ end::front ].CouplingFlag & ctrain_power ) == ctrain_power )
|
||||||
|| ( ( Couplers[ end::rear ].CouplingFlag & ctrain_power ) == ctrain_power ) ) ) {
|
|| ( ( Couplers[ end::rear ].CouplingFlag & ctrain_power ) == ctrain_power ) ) ) {
|
||||||
@@ -4423,7 +4549,7 @@ double TMoverParameters::TractionForce( double dt ) {
|
|||||||
|
|
||||||
tmp = DElist[ MainCtrlPos ].RPM / 60.0;
|
tmp = DElist[ MainCtrlPos ].RPM / 60.0;
|
||||||
|
|
||||||
if( ( true == Heating )
|
if( ( true == HeatingAllow )
|
||||||
&& ( HeatingPower > 0 )
|
&& ( HeatingPower > 0 )
|
||||||
&& ( EngineHeatingRPM > 0 ) ) {
|
&& ( EngineHeatingRPM > 0 ) ) {
|
||||||
// bump engine revolutions up if needed, when heating is on
|
// bump engine revolutions up if needed, when heating is on
|
||||||
@@ -4577,7 +4703,7 @@ double TMoverParameters::TractionForce( double dt ) {
|
|||||||
EnginePower = ( 2 * dizel_Mstand + dmoment ) * enrot * ( 2.0 * M_PI / 1000.0 );
|
EnginePower = ( 2 * dizel_Mstand + dmoment ) * enrot * ( 2.0 * M_PI / 1000.0 );
|
||||||
if( MainCtrlPowerPos() > 1 ) {
|
if( MainCtrlPowerPos() > 1 ) {
|
||||||
// dodatkowe opory z powodu sprezarki}
|
// dodatkowe opory z powodu sprezarki}
|
||||||
dmoment -= dizel_Mstand * ( 0.2 * enrot / dizel_nmax );
|
// dmoment -= dizel_Mstand * ( 0.2 * enrot / dizel_nmax ); //yB: skąd to w ogóle się bierze?!
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -4760,6 +4886,8 @@ double TMoverParameters::TractionForce( double dt ) {
|
|||||||
{
|
{
|
||||||
Mm = dmoment; //bylo * dizel_engage
|
Mm = dmoment; //bylo * dizel_engage
|
||||||
Mw = Mm * dtrans; // dmoment i dtrans policzone przy okazji enginerotation
|
Mw = Mm * dtrans; // dmoment i dtrans policzone przy okazji enginerotation
|
||||||
|
if ((hydro_R) && (hydro_R_Placement == 0))
|
||||||
|
Mw -= dizel_MomentumRetarder(nrot * Transmision.Ratio, dt) * Transmision.Ratio;
|
||||||
Fw = Mw * 2.0 / WheelDiameter / NPoweredAxles;
|
Fw = Mw * 2.0 / WheelDiameter / NPoweredAxles;
|
||||||
Ft = Fw * NPoweredAxles; // sila trakcyjna
|
Ft = Fw * NPoweredAxles; // sila trakcyjna
|
||||||
Ft = Ft * DirAbsolute; // ActiveDir*CabNo;
|
Ft = Ft * DirAbsolute; // ActiveDir*CabNo;
|
||||||
@@ -5300,12 +5428,12 @@ double TMoverParameters::TractionForce( double dt ) {
|
|||||||
Im = eimv[eimv_If];
|
Im = eimv[eimv_If];
|
||||||
if ((eimv[eimv_Ipoj] >= 0))
|
if ((eimv[eimv_Ipoj] >= 0))
|
||||||
Vadd *= (1.0 - 2.0 * dt);
|
Vadd *= (1.0 - 2.0 * dt);
|
||||||
else if ((Voltage < EnginePowerSource.CollectorParameters.MaxV))
|
else if ((std::abs(Voltage) < EnginePowerSource.CollectorParameters.MaxV))
|
||||||
Vadd *= (1.0 - dt);
|
Vadd *= (1.0 - dt);
|
||||||
else
|
else
|
||||||
Vadd = Max0R(
|
Vadd = Max0R(
|
||||||
Vadd * (1.0 - 0.2 * dt),
|
Vadd * (1.0 - 0.2 * dt),
|
||||||
0.007 * (Voltage - (EnginePowerSource.CollectorParameters.MaxV - 100)));
|
0.007 * (std::abs(Voltage) - (EnginePowerSource.CollectorParameters.MaxV - 100)));
|
||||||
Itot = eimv[eimv_Ipoj] * (0.01 + Min0R(0.99, 0.99 - Vadd));
|
Itot = eimv[eimv_Ipoj] * (0.01 + Min0R(0.99, 0.99 - Vadd));
|
||||||
|
|
||||||
EnginePower = abs(eimv[eimv_Ic] * eimv[eimv_U] * NPoweredAxles) / 1000;
|
EnginePower = abs(eimv[eimv_Ic] * eimv[eimv_U] * NPoweredAxles) / 1000;
|
||||||
@@ -6124,10 +6252,35 @@ void TMoverParameters::CheckEIMIC(double dt)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
eimic -= clamp(-UniCtrlList[MainCtrlPos].SetCtrlVal + eimic, 0.0, dt * UniCtrlList[MainCtrlPos].SpeedDown); //odejmuj do X
|
if ((UniCtrlList[MainCtrlPos].mode != BrakeCtrlPos) && (MainCtrlActualPos == MainCtrlPos)) //there was no move of controller, but brake only
|
||||||
eimic += clamp(UniCtrlList[MainCtrlPos].SetCtrlVal - eimic, 0.0, dt * UniCtrlList[MainCtrlPos].SpeedUp); //dodawaj do X
|
{
|
||||||
|
if (BrakeCtrlPos < UniCtrlList[MainCtrlPosNo].mode)
|
||||||
|
BrakeLevelSet(UniCtrlList[MainCtrlPosNo].mode); //bottom clamping
|
||||||
|
if (BrakeCtrlPos > UniCtrlList[0].mode)
|
||||||
|
BrakeLevelSet(UniCtrlList[0].mode); //top clamping
|
||||||
|
while (BrakeCtrlPos > UniCtrlList[MainCtrlPos].mode) DecMainCtrl(1); //find nearest position
|
||||||
|
while (BrakeCtrlPos < UniCtrlList[MainCtrlPos].mode) IncMainCtrl(1); //find nearest position
|
||||||
|
}
|
||||||
|
else //controller was moved
|
||||||
|
BrakeLevelSet(UniCtrlList[MainCtrlPos].mode);
|
||||||
|
|
||||||
|
if ((MainCtrlActualPos != MainCtrlPos) || (LastRelayTime>InitialCtrlDelay))
|
||||||
|
{
|
||||||
|
eimic -= clamp(-UniCtrlList[MainCtrlPos].SetCtrlVal + eimic, 0.0, (MainCtrlActualPos == MainCtrlPos ? dt * UniCtrlList[MainCtrlPos].SpeedDown : sign(UniCtrlList[MainCtrlPos].SpeedDown) * 0.01)); //odejmuj do X
|
||||||
|
eimic += clamp(UniCtrlList[MainCtrlPos].SetCtrlVal - eimic, 0.0, (MainCtrlActualPos == MainCtrlPos ? dt * UniCtrlList[MainCtrlPos].SpeedUp : sign(UniCtrlList[MainCtrlPos].SpeedUp) * 0.01)); //dodawaj do X
|
||||||
eimic = clamp(eimic, UniCtrlList[MainCtrlPos].MinCtrlVal, UniCtrlList[MainCtrlPos].MaxCtrlVal);
|
eimic = clamp(eimic, UniCtrlList[MainCtrlPos].MinCtrlVal, UniCtrlList[MainCtrlPos].MaxCtrlVal);
|
||||||
}
|
}
|
||||||
|
if (MainCtrlActualPos == MainCtrlPos)
|
||||||
|
LastRelayTime += dt;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LastRelayTime = 0;
|
||||||
|
MainCtrlActualPos = MainCtrlPos;
|
||||||
|
}
|
||||||
|
if (Hamulec->GetEDBCP() > 0.3 && eimic < 0) //when braking with pneumatic brake
|
||||||
|
eimic = 0; //shut off retarder
|
||||||
|
|
||||||
|
}
|
||||||
auto const eimicpowerenabled {
|
auto const eimicpowerenabled {
|
||||||
( ( true == Mains ) || ( Power == 0.0 ) )
|
( ( true == Mains ) || ( Power == 0.0 ) )
|
||||||
&& ( ( Doors.instances[ side::left ].open_permit == false )
|
&& ( ( Doors.instances[ side::left ].open_permit == false )
|
||||||
@@ -6249,6 +6402,22 @@ bool TMoverParameters::dizel_AutoGearCheck(void)
|
|||||||
|
|
||||||
if (Mains)
|
if (Mains)
|
||||||
{
|
{
|
||||||
|
if (EIMCtrlType > 0) //sterowanie komputerowe
|
||||||
|
{
|
||||||
|
if (dizel_automaticgearstatus == 0)
|
||||||
|
{
|
||||||
|
if ((hydro_TC && hydro_TC_Fill > 0.01) || (eimic_real > 0.0))
|
||||||
|
dizel_EngageSwitch(1.0);
|
||||||
|
else
|
||||||
|
if (Vel > hydro_R_EngageVel && hydro_R && hydro_R_Fill > 0.01)
|
||||||
|
dizel_EngageSwitch(0.5);
|
||||||
|
else
|
||||||
|
dizel_EngageSwitch(0.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dizel_EngageSwitch(0.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
if (dizel_automaticgearstatus == 0) // ustaw cisnienie w silowniku sprzegla}
|
if (dizel_automaticgearstatus == 0) // ustaw cisnienie w silowniku sprzegla}
|
||||||
switch (RList[MainCtrlPos].Mn)
|
switch (RList[MainCtrlPos].Mn)
|
||||||
{
|
{
|
||||||
@@ -6380,7 +6549,7 @@ bool TMoverParameters::dizel_Update(double dt) {
|
|||||||
dizel_EngageChange( dt );
|
dizel_EngageChange( dt );
|
||||||
DU = dizel_AutoGearCheck();
|
DU = dizel_AutoGearCheck();
|
||||||
double const fillspeed { 2 };
|
double const fillspeed { 2 };
|
||||||
dizel_fill = dizel_fill + fillspeed * dt * ( dizel_fillcheck( MainCtrlPos ) - dizel_fill );
|
dizel_fill = dizel_fill + fillspeed * dt * ( dizel_fillcheck( MainCtrlPos , dt ) - dizel_fill );
|
||||||
}
|
}
|
||||||
|
|
||||||
dizel_Heat( dt );
|
dizel_Heat( dt );
|
||||||
@@ -6392,7 +6561,7 @@ bool TMoverParameters::dizel_Update(double dt) {
|
|||||||
// Q: 20160715
|
// Q: 20160715
|
||||||
// oblicza napelnienie, uzwglednia regulator obrotow
|
// oblicza napelnienie, uzwglednia regulator obrotow
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
double TMoverParameters::dizel_fillcheck(int mcp)
|
double TMoverParameters::dizel_fillcheck(int mcp, double dt)
|
||||||
{
|
{
|
||||||
auto realfill { 0.0 };
|
auto realfill { 0.0 };
|
||||||
|
|
||||||
@@ -6409,11 +6578,30 @@ double TMoverParameters::dizel_fillcheck(int mcp)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// napelnienie zalezne od MainCtrlPos
|
// napelnienie zalezne od MainCtrlPos
|
||||||
|
if (EIMCtrlType > 0)
|
||||||
|
{
|
||||||
|
realfill = std::max(0.0, eimic_real);
|
||||||
|
if (eimic_real>0 && !hydro_TC_Lockup)
|
||||||
|
{
|
||||||
|
dizel_nreg_min = std::min(dizel_nreg_min + 2.5 * dt, dizel_nmin_hdrive + eimic_real * dizel_nmin_hdrive_factor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Vel < hydro_R_EngageVel && hydro_R && hydro_R_Fill > 0.01)
|
||||||
|
dizel_nreg_min = std::min(dizel_nreg_min + 5.0 * dt, dizel_nmin_retarder);
|
||||||
|
else
|
||||||
|
dizel_nreg_min = dizel_nmin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
realfill = RList[mcp].R;
|
realfill = RList[mcp].R;
|
||||||
}
|
}
|
||||||
if (dizel_nmax_cutoff > 0)
|
if (dizel_nmax_cutoff > 0)
|
||||||
{
|
{
|
||||||
auto nreg { 0.0 };
|
auto nreg { 0.0 };
|
||||||
|
if (EIMCtrlType > 0)
|
||||||
|
nreg = (eimic_real > 0 ? dizel_nmax : dizel_nmin);
|
||||||
|
else
|
||||||
switch (RList[MainCtrlPos].Mn)
|
switch (RList[MainCtrlPos].Mn)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@@ -6452,7 +6640,7 @@ double TMoverParameters::dizel_fillcheck(int mcp)
|
|||||||
realfill = 0;
|
realfill = 0;
|
||||||
if (enrot < nreg) //pod predkoscia regulatora dawka zadana
|
if (enrot < nreg) //pod predkoscia regulatora dawka zadana
|
||||||
realfill = realfill;
|
realfill = realfill;
|
||||||
if ((enrot < dizel_nmin * 0.98)&&(RList[mcp].R>0.001)) //jesli ponizej biegu jalowego i niezerowa dawka, to dawaj pelna
|
if ((enrot < dizel_nreg_min)&&(RList[mcp].R>0.001)) //jesli ponizej biegu jalowego i niezerowa dawka, to dawaj pelna
|
||||||
realfill = 1;
|
realfill = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6478,6 +6666,8 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
|
|||||||
|
|
||||||
if( enrot > 0 ) {
|
if( enrot > 0 ) {
|
||||||
Moment = ( dizel_Mmax - ( dizel_Mmax - dizel_Mnmax ) * square( ( enrot - dizel_nMmax ) / ( dizel_nMmax - dizel_nmax ) ) ) * dizel_fill - dizel_Mstand;
|
Moment = ( dizel_Mmax - ( dizel_Mmax - dizel_Mnmax ) * square( ( enrot - dizel_nMmax ) / ( dizel_nMmax - dizel_nmax ) ) ) * dizel_fill - dizel_Mstand;
|
||||||
|
if ((hydro_R) && (hydro_R_Placement == 2))
|
||||||
|
Moment -= dizel_MomentumRetarder(enrot, dt);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Moment = -dizel_Mstand;
|
Moment = -dizel_Mstand;
|
||||||
@@ -6495,10 +6685,11 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
|
|||||||
if (hydro_TC) //jesli przetwornik momentu
|
if (hydro_TC) //jesli przetwornik momentu
|
||||||
{
|
{
|
||||||
//napelnianie przetwornika
|
//napelnianie przetwornika
|
||||||
if ((MainCtrlPowerPos() > 0) && (Mains) && (enrot>dizel_nmin*0.9))
|
bool IsPower = (EIMCtrlType > 0 ? eimic_real > 0 : MainCtrlPowerPos() > 0);
|
||||||
|
if ((IsPower) && (Mains) && (enrot>dizel_nmin*0.9))
|
||||||
hydro_TC_Fill += hydro_TC_FillRateInc * dt;
|
hydro_TC_Fill += hydro_TC_FillRateInc * dt;
|
||||||
//oproznianie przetwornika
|
//oproznianie przetwornika
|
||||||
if (((IsMainCtrlNoPowerPos()) && (Vel<3))
|
if (((!IsPower) && (Vel<dizel_maxVelANS))
|
||||||
|| (!Mains)
|
|| (!Mains)
|
||||||
|| (enrot<dizel_nmin*0.8))
|
|| (enrot<dizel_nmin*0.8))
|
||||||
hydro_TC_Fill -= hydro_TC_FillRateDec * dt;
|
hydro_TC_Fill -= hydro_TC_FillRateDec * dt;
|
||||||
@@ -6506,10 +6697,10 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
|
|||||||
hydro_TC_Fill = clamp(hydro_TC_Fill, 0.0, 1.0);
|
hydro_TC_Fill = clamp(hydro_TC_Fill, 0.0, 1.0);
|
||||||
|
|
||||||
//blokowanie sprzegla blokującego
|
//blokowanie sprzegla blokującego
|
||||||
if ((Vel > hydro_TC_LockupSpeed) && (Mains) && (enrot > 0.9 * dizel_nmin) && (MainCtrlPowerPos() > 0))
|
if ((Vel > hydro_TC_LockupSpeed) && (Mains) && (enrot > 0.9 * dizel_nmin) && (IsPower))
|
||||||
hydro_TC_LockupRate += hydro_TC_FillRateInc*dt;
|
hydro_TC_LockupRate += hydro_TC_FillRateInc*dt;
|
||||||
//luzowanie sprzegla blokujacego
|
//luzowanie sprzegla blokujacego
|
||||||
if ((Vel < (MainCtrlPowerPos() > 0 ? hydro_TC_LockupSpeed : hydro_TC_UnlockSpeed)) || (!Mains) || (enrot < 0.8 * dizel_nmin))
|
if ((Vel < (IsPower ? hydro_TC_LockupSpeed : hydro_TC_UnlockSpeed)) || (!Mains) || (enrot < 0.8 * dizel_nmin))
|
||||||
hydro_TC_LockupRate -= hydro_TC_FillRateDec*dt;
|
hydro_TC_LockupRate -= hydro_TC_FillRateDec*dt;
|
||||||
//obcinanie zakresu
|
//obcinanie zakresu
|
||||||
hydro_TC_LockupRate = clamp(hydro_TC_LockupRate, 0.0, 1.0);
|
hydro_TC_LockupRate = clamp(hydro_TC_LockupRate, 0.0, 1.0);
|
||||||
@@ -6596,6 +6787,8 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
|
|||||||
double enrot_max = enrot + (Min0R(TorqueC, TorqueL + abs(hydro_TC_TorqueIn)) + Moment) / dizel_AIM * dt;
|
double enrot_max = enrot + (Min0R(TorqueC, TorqueL + abs(hydro_TC_TorqueIn)) + Moment) / dizel_AIM * dt;
|
||||||
enrot = clamp(n,enrot_min,enrot_max);
|
enrot = clamp(n,enrot_min,enrot_max);
|
||||||
}
|
}
|
||||||
|
if ((hydro_R) && (hydro_R_Placement == 1))
|
||||||
|
gearMoment -= dizel_MomentumRetarder(hydro_TC_nOut, dt);
|
||||||
|
|
||||||
|
|
||||||
if( ( enrot <= 0 ) && ( false == dizel_spinup ) ) {
|
if( ( enrot <= 0 ) && ( false == dizel_spinup ) ) {
|
||||||
@@ -6608,6 +6801,40 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
|
|||||||
return gearMoment;
|
return gearMoment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double TMoverParameters::dizel_MomentumRetarder(double n, double dt)
|
||||||
|
{
|
||||||
|
double RetarderRequest = (Mains ? std::max(0.0, -eimic_real) : 0);
|
||||||
|
if (Vel < hydro_R_MinVel)
|
||||||
|
RetarderRequest = 0;
|
||||||
|
if ((hydro_R_Placement == 2) && (enrot < dizel_nmin))
|
||||||
|
{
|
||||||
|
RetarderRequest = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hydro_R_n = n * 60;
|
||||||
|
|
||||||
|
if (hydro_R_Fill < RetarderRequest) //gdy zadane hamowanie
|
||||||
|
{
|
||||||
|
hydro_R_Fill = std::min(hydro_R_Fill + hydro_R_FillRateInc*dt, RetarderRequest);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hydro_R_Fill = std::max(hydro_R_Fill - hydro_R_FillRateDec*dt, RetarderRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
double Moment = hydro_R_MaxTorque;
|
||||||
|
double pwr = Moment * n * M_PI * 2 * 0.001;
|
||||||
|
if (pwr > hydro_R_MaxPower)
|
||||||
|
Moment = Moment * hydro_R_MaxPower / pwr;
|
||||||
|
double moment_in = n*n*hydro_R_TorqueInIn;
|
||||||
|
Moment = std::min(moment_in, Moment * hydro_R_Fill);
|
||||||
|
|
||||||
|
hydro_R_Torque = Moment;
|
||||||
|
|
||||||
|
return Moment;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// sets component temperatures to specified value
|
// sets component temperatures to specified value
|
||||||
void TMoverParameters::dizel_HeatSet( float const Value ) {
|
void TMoverParameters::dizel_HeatSet( float const Value ) {
|
||||||
|
|
||||||
@@ -6917,8 +7144,8 @@ bool TMoverParameters::ChangeDoorPermitPreset( int const Change, range_t const N
|
|||||||
|
|
||||||
Doors.permit_preset = clamp<int>( Doors.permit_preset + Change, 0, Doors.permit_presets.size() - 1 );
|
Doors.permit_preset = clamp<int>( Doors.permit_preset + Change, 0, Doors.permit_presets.size() - 1 );
|
||||||
auto const doors { Doors.permit_presets[ Doors.permit_preset ] };
|
auto const doors { Doors.permit_presets[ Doors.permit_preset ] };
|
||||||
auto const permitleft = doors & 1;
|
auto const permitleft { ( ( doors & 1 ) != 0 ) };
|
||||||
auto const permitright = doors & 2;
|
auto const permitright { ( ( doors & 2 ) != 0 ) };
|
||||||
|
|
||||||
PermitDoors( ( CabNo > 0 ? side::left : side::right ), permitleft, Notify );
|
PermitDoors( ( CabNo > 0 ? side::left : side::right ), permitleft, Notify );
|
||||||
PermitDoors( ( CabNo > 0 ? side::right : side::left ), permitright, Notify );
|
PermitDoors( ( CabNo > 0 ? side::right : side::left ), permitright, Notify );
|
||||||
@@ -7376,15 +7603,11 @@ double TMoverParameters::GetTrainsetVoltage(void)
|
|||||||
{//ABu: funkcja zwracajaca napiecie dla calego skladu, przydatna dla EZT
|
{//ABu: funkcja zwracajaca napiecie dla calego skladu, przydatna dla EZT
|
||||||
return std::max(
|
return std::max(
|
||||||
( ( ( Couplers[end::front].Connected )
|
( ( ( Couplers[end::front].Connected )
|
||||||
&& ( ( Couplers[ end::front ].CouplingFlag & ctrain_power )
|
&& ( Couplers[ end::front ].Connected->Couplers[ Couplers[ end::front ].ConnectedNr ].power_high.is_live ) ) ?
|
||||||
|| ( ( Couplers[ end::front ].CouplingFlag & ctrain_heating )
|
|
||||||
&& ( Couplers[ end::front ].Connected->Heating ) ) ) ) ?
|
|
||||||
Couplers[end::front].Connected->Couplers[ Couplers[end::front].ConnectedNr ].power_high.voltage :
|
Couplers[end::front].Connected->Couplers[ Couplers[end::front].ConnectedNr ].power_high.voltage :
|
||||||
0.0 ),
|
0.0 ),
|
||||||
( ( ( Couplers[end::rear].Connected )
|
( ( ( Couplers[end::rear].Connected )
|
||||||
&& ( ( Couplers[ end::rear ].CouplingFlag & ctrain_power )
|
&& ( Couplers[ end::rear ].Connected->Couplers[ Couplers[ end::rear ].ConnectedNr ].power_high.is_live ) ) ?
|
||||||
|| ( ( Couplers[ end::rear ].CouplingFlag & ctrain_heating )
|
|
||||||
&& ( Couplers[ end::rear ].Connected->Heating ) ) ) ) ?
|
|
||||||
Couplers[ end::rear ].Connected->Couplers[ Couplers[ end::rear ].ConnectedNr ].power_high.voltage :
|
Couplers[ end::rear ].Connected->Couplers[ Couplers[ end::rear ].ConnectedNr ].power_high.voltage :
|
||||||
0.0 ) );
|
0.0 ) );
|
||||||
}
|
}
|
||||||
@@ -7826,13 +8049,19 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
|
|||||||
std::string file = chkpath + TypeName + ".fiz";
|
std::string file = chkpath + TypeName + ".fiz";
|
||||||
|
|
||||||
WriteLog("LOAD FIZ FROM " + file);
|
WriteLog("LOAD FIZ FROM " + file);
|
||||||
|
/*
|
||||||
std::ifstream in(file);
|
std::ifstream in(file);
|
||||||
if (!in.is_open())
|
if (!in.is_open())
|
||||||
{
|
{
|
||||||
WriteLog("E8 - FIZ FILE NOT EXIST.");
|
WriteLog("E8 - FIZ FILE NOT EXIST.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
cParser fizparser( file, cParser::buffer_FILE );
|
||||||
|
if( false == fizparser.ok() ) {
|
||||||
|
WriteLog( "E8 - FIZ FILE NOT EXIST." );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ConversionError = 0;
|
ConversionError = 0;
|
||||||
|
|
||||||
@@ -7840,8 +8069,13 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
|
|||||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
std::unordered_map<std::string, std::string> fizlines;
|
std::unordered_map<std::string, std::string> fizlines;
|
||||||
std::string inputline;
|
std::string inputline;
|
||||||
|
/*
|
||||||
while (std::getline(in, inputline))
|
while (std::getline(in, inputline))
|
||||||
{
|
*/
|
||||||
|
while( fizparser.ok() ) {
|
||||||
|
|
||||||
|
inputline = fizparser.getToken<std::string>( false, "\n" );
|
||||||
|
|
||||||
bool comment = ( ( inputline.find('#') != std::string::npos )
|
bool comment = ( ( inputline.find('#') != std::string::npos )
|
||||||
|| ( inputline.compare( 0, 2, "//" ) == 0 ) );
|
|| ( inputline.compare( 0, 2, "//" ) == 0 ) );
|
||||||
if( true == comment ) {
|
if( true == comment ) {
|
||||||
@@ -7875,7 +8109,7 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
|
|||||||
startRLIST = false;
|
startRLIST = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (issection("END-RL", inputline)) {
|
if (issection("END-UCL", inputline)) {
|
||||||
startBPT = false;
|
startBPT = false;
|
||||||
startUCLIST = false;
|
startUCLIST = false;
|
||||||
continue;
|
continue;
|
||||||
@@ -8088,7 +8322,7 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
|
|||||||
startBPT = false;
|
startBPT = false;
|
||||||
fizlines.emplace("UCList", inputline);
|
fizlines.emplace("UCList", inputline);
|
||||||
startUCLIST = true; LISTLINE = 0;
|
startUCLIST = true; LISTLINE = 0;
|
||||||
LoadFIZ_RList(inputline);
|
LoadFIZ_UCList(inputline);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8142,7 +8376,7 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (true == startUCLIST) {
|
if (true == startUCLIST) {
|
||||||
readRList(inputline);
|
readUCList(inputline);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if( true == startDLIST ) {
|
if( true == startDLIST ) {
|
||||||
@@ -8162,8 +8396,9 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} // while line
|
} // while line
|
||||||
|
/*
|
||||||
in.close();
|
in.close();
|
||||||
|
*/
|
||||||
// Operacje na zebranych parametrach - przypisywanie do wlasciwych zmiennych i ustawianie
|
// Operacje na zebranych parametrach - przypisywanie do wlasciwych zmiennych i ustawianie
|
||||||
// zaleznosci
|
// zaleznosci
|
||||||
|
|
||||||
@@ -8774,6 +9009,8 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
|
|||||||
false;
|
false;
|
||||||
extract_value(SpeedCtrlAutoTurnOffFlag, "SpeedCtrlATOF", line, "");
|
extract_value(SpeedCtrlAutoTurnOffFlag, "SpeedCtrlATOF", line, "");
|
||||||
|
|
||||||
|
// main circuit
|
||||||
|
extract_value( MainsInitTime, "MainInitTime", line, "" );
|
||||||
// converter
|
// converter
|
||||||
{
|
{
|
||||||
std::map<std::string, start_t> starts {
|
std::map<std::string, start_t> starts {
|
||||||
@@ -8811,6 +9048,9 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
|
|||||||
lookup->second :
|
lookup->second :
|
||||||
start_t::manual;
|
start_t::manual;
|
||||||
}
|
}
|
||||||
|
// pantograph compressor valve
|
||||||
|
PantAutoValve = ( TrainType == dt_EZT ); // legacy code behaviour, automatic valve was initially installed in all EMUs
|
||||||
|
extract_value( PantAutoValve, "PantAutoValve", line, "" );
|
||||||
// fuel pump
|
// fuel pump
|
||||||
{
|
{
|
||||||
auto lookup = starts.find( extract_value( "FuelStart", line ) );
|
auto lookup = starts.find( extract_value( "FuelStart", line ) );
|
||||||
@@ -8849,9 +9089,9 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
|
|||||||
void TMoverParameters::LoadFIZ_Blending(std::string const &line) {
|
void TMoverParameters::LoadFIZ_Blending(std::string const &line) {
|
||||||
|
|
||||||
extract_value(MED_Vmax, "MED_Vmax", line, to_string(Vmax));
|
extract_value(MED_Vmax, "MED_Vmax", line, to_string(Vmax));
|
||||||
extract_value(MED_Vmin, "MED_Vmin", line, "0");
|
extract_value(MED_Vmin, "MED_Vmin", line, "");
|
||||||
extract_value(MED_Vref, "MED_Vref", line, to_string(Vmax));
|
extract_value(MED_Vref, "MED_Vref", line, to_string(Vmax));
|
||||||
extract_value(MED_amax, "MED_amax", line, "9.81");
|
extract_value(MED_amax, "MED_amax", line, "");
|
||||||
extract_value(MED_EPVC, "MED_EPVC", line, "");
|
extract_value(MED_EPVC, "MED_EPVC", line, "");
|
||||||
extract_value(MED_Ncor, "MED_Ncor", line, "");
|
extract_value(MED_Ncor, "MED_Ncor", line, "");
|
||||||
|
|
||||||
@@ -8859,10 +9099,10 @@ void TMoverParameters::LoadFIZ_Blending(std::string const &line) {
|
|||||||
|
|
||||||
void TMoverParameters::LoadFIZ_DCEMUED(std::string const &line) {
|
void TMoverParameters::LoadFIZ_DCEMUED(std::string const &line) {
|
||||||
|
|
||||||
extract_value(DCEMUED_CC, "CouplerCheck", line, "0");
|
extract_value(DCEMUED_CC, "CouplerCheck", line, "");
|
||||||
extract_value(DCEMUED_EP_max_Vel, "EP_max_Vel", line, "0");
|
extract_value(DCEMUED_EP_max_Vel, "EP_max_Vel", line, "");
|
||||||
extract_value(DCEMUED_EP_min_Im, "EP_min_Im", line, "0");
|
extract_value(DCEMUED_EP_min_Im, "EP_min_Im", line, "");
|
||||||
extract_value(DCEMUED_EP_delay, "EP_delay", line, "0");
|
extract_value(DCEMUED_EP_delay, "EP_delay", line, "");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8909,12 +9149,13 @@ void TMoverParameters::LoadFIZ_Power( std::string const &Line ) {
|
|||||||
|
|
||||||
EnginePowerSource.SourceType = LoadFIZ_SourceDecode( extract_value( "EnginePower", Line ) );
|
EnginePowerSource.SourceType = LoadFIZ_SourceDecode( extract_value( "EnginePower", Line ) );
|
||||||
LoadFIZ_PowerParamsDecode( EnginePowerSource, "", Line );
|
LoadFIZ_PowerParamsDecode( EnginePowerSource, "", Line );
|
||||||
|
/*
|
||||||
if( ( EnginePowerSource.SourceType == TPowerSource::Generator )
|
if( ( EnginePowerSource.SourceType == TPowerSource::Generator )
|
||||||
&& ( EnginePowerSource.GeneratorEngine == TEngineType::WheelsDriven ) ) {
|
&& ( EnginePowerSource.GeneratorEngine == TEngineType::WheelsDriven ) ) {
|
||||||
// perpetuum mobile?
|
// perpetuum mobile?
|
||||||
ConversionError = 666;
|
ConversionError = 666;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if( Power == 0.0 ) {
|
if( Power == 0.0 ) {
|
||||||
//jeśli nie ma mocy, np. rozrządcze EZT
|
//jeśli nie ma mocy, np. rozrządcze EZT
|
||||||
EnginePowerSource.SourceType = TPowerSource::NotDefined;
|
EnginePowerSource.SourceType = TPowerSource::NotDefined;
|
||||||
@@ -8970,6 +9211,19 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
|||||||
|
|
||||||
extract_value( dizel_nmin, "nmin", Input, "" );
|
extract_value( dizel_nmin, "nmin", Input, "" );
|
||||||
dizel_nmin /= 60.0;
|
dizel_nmin /= 60.0;
|
||||||
|
dizel_nreg_min = dizel_nmin * 0.98;
|
||||||
|
extract_value(dizel_nmin_hdrive, "nmin_hdrive", Input, "");
|
||||||
|
dizel_nmin_hdrive /= 60.0;
|
||||||
|
if (dizel_nmin_hdrive == 0.0) {
|
||||||
|
dizel_nmin_hdrive = dizel_nmin;
|
||||||
|
}
|
||||||
|
extract_value(dizel_nmin_hdrive_factor, "nmin_hdrive_factor", Input, "");
|
||||||
|
dizel_nmin_hdrive_factor /= 60.0;
|
||||||
|
extract_value(dizel_nmin_retarder, "nmin_retarder", Input, "");
|
||||||
|
dizel_nmin_retarder /= 60.0;
|
||||||
|
if (dizel_nmin_retarder == 0.0) {
|
||||||
|
dizel_nmin_retarder = dizel_nmin;
|
||||||
|
}
|
||||||
// TODO: unify naming scheme and sort out which diesel engine params are used where and how
|
// TODO: unify naming scheme and sort out which diesel engine params are used where and how
|
||||||
extract_value( nmax, "nmax", Input, "" );
|
extract_value( nmax, "nmax", Input, "" );
|
||||||
nmax /= 60.0;
|
nmax /= 60.0;
|
||||||
@@ -9004,6 +9258,7 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
|||||||
extract_value(hydro_TC_TorqueOutOut, "TC_TOO", Input, "");
|
extract_value(hydro_TC_TorqueOutOut, "TC_TOO", Input, "");
|
||||||
extract_value(hydro_TC_LockupSpeed, "TC_LS", Input, "");
|
extract_value(hydro_TC_LockupSpeed, "TC_LS", Input, "");
|
||||||
extract_value(hydro_TC_UnlockSpeed, "TC_ULS", Input, "");
|
extract_value(hydro_TC_UnlockSpeed, "TC_ULS", Input, "");
|
||||||
|
extract_value(dizel_maxVelANS, "MaxVelANS", Input, "");
|
||||||
|
|
||||||
extract_value(hydro_R, "IsRetarder", Input, "");
|
extract_value(hydro_R, "IsRetarder", Input, "");
|
||||||
if (true == hydro_R) {
|
if (true == hydro_R) {
|
||||||
@@ -9014,6 +9269,7 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
|||||||
extract_value(hydro_R_FillRateInc, "R_FRI", Input, "");
|
extract_value(hydro_R_FillRateInc, "R_FRI", Input, "");
|
||||||
extract_value(hydro_R_FillRateDec, "R_FRD", Input, "");
|
extract_value(hydro_R_FillRateDec, "R_FRD", Input, "");
|
||||||
extract_value(hydro_R_MinVel, "R_MinVel", Input, "");
|
extract_value(hydro_R_MinVel, "R_MinVel", Input, "");
|
||||||
|
extract_value(hydro_R_EngageVel, "R_EngageVel", Input, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -9237,12 +9493,31 @@ void TMoverParameters::LoadFIZ_PowerParamsDecode( TPowerParameters &Powerparamet
|
|||||||
}
|
}
|
||||||
case TPowerSource::Transducer: {
|
case TPowerSource::Transducer: {
|
||||||
|
|
||||||
extract_value( Powerparameters.InputVoltage, Prefix + "TransducerInputV", Line, "" );
|
extract_value( Powerparameters.Transducer.InputVoltage, Prefix + "TransducerInputV", Line, "" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TPowerSource::Generator: {
|
case TPowerSource::Generator: {
|
||||||
|
// prime mover for the generator
|
||||||
|
auto &generatorparameters { Powerparameters.EngineGenerator };
|
||||||
|
|
||||||
Powerparameters.GeneratorEngine = LoadFIZ_EngineDecode( extract_value( Prefix + "GeneratorEngine", Line ) );
|
auto const enginetype { LoadFIZ_EngineDecode( extract_value( Prefix + "GeneratorEngine", Line ) ) };
|
||||||
|
if( enginetype == TEngineType::Main ) {
|
||||||
|
generatorparameters.engine_revolutions = &enrot;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// TODO: for engine types other than Main create requested engine object and link to its revolutions
|
||||||
|
generatorparameters.engine_revolutions = nullptr;
|
||||||
|
generatorparameters.revolutions = 0;
|
||||||
|
generatorparameters.voltage = 0;
|
||||||
|
}
|
||||||
|
// config
|
||||||
|
extract_value( generatorparameters.voltage_min, Prefix + "GeneratorMinVoltage", Line, "0" );
|
||||||
|
extract_value( generatorparameters.voltage_max, Prefix + "GeneratorMaxVoltage", Line, "0" );
|
||||||
|
// NOTE: for consistency the fiz file specifies revolutions per minute
|
||||||
|
extract_value( generatorparameters.revolutions_min, Prefix + "GeneratorMinRPM", Line, "0" );
|
||||||
|
extract_value( generatorparameters.revolutions_max, Prefix + "GeneratorMaxRPM", Line, "0" );
|
||||||
|
generatorparameters.revolutions_min /= 60;
|
||||||
|
generatorparameters.revolutions_max /= 60;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TPowerSource::Accumulator: {
|
case TPowerSource::Accumulator: {
|
||||||
@@ -9328,7 +9603,8 @@ TPowerSource TMoverParameters::LoadFIZ_SourceDecode( std::string const &Source )
|
|||||||
{ "CurrentCollector", TPowerSource::CurrentCollector },
|
{ "CurrentCollector", TPowerSource::CurrentCollector },
|
||||||
{ "PowerCable", TPowerSource::PowerCable },
|
{ "PowerCable", TPowerSource::PowerCable },
|
||||||
{ "Heater", TPowerSource::Heater },
|
{ "Heater", TPowerSource::Heater },
|
||||||
{ "Internal", TPowerSource::InternalSource }
|
{ "Internal", TPowerSource::InternalSource },
|
||||||
|
{ "Main", TPowerSource::Main }
|
||||||
};
|
};
|
||||||
auto lookup = powersources.find( Source );
|
auto lookup = powersources.find( Source );
|
||||||
return
|
return
|
||||||
@@ -9347,7 +9623,8 @@ TEngineType TMoverParameters::LoadFIZ_EngineDecode( std::string const &Engine )
|
|||||||
{ "Dumb", TEngineType::Dumb },
|
{ "Dumb", TEngineType::Dumb },
|
||||||
{ "DieselElectric", TEngineType::DieselElectric },
|
{ "DieselElectric", TEngineType::DieselElectric },
|
||||||
{ "DumbDE", TEngineType::DieselElectric },
|
{ "DumbDE", TEngineType::DieselElectric },
|
||||||
{ "ElectricInductionMotor", TEngineType::ElectricInductionMotor }
|
{ "ElectricInductionMotor", TEngineType::ElectricInductionMotor },
|
||||||
|
{ "Main", TEngineType::Main }
|
||||||
};
|
};
|
||||||
auto lookup = enginetypes.find( Engine );
|
auto lookup = enginetypes.find( Engine );
|
||||||
return
|
return
|
||||||
@@ -9565,6 +9842,17 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
|
|||||||
if( LightsPosNo > 0 )
|
if( LightsPosNo > 0 )
|
||||||
LightsPos = LightsDefPos;
|
LightsPos = LightsDefPos;
|
||||||
|
|
||||||
|
// NOTE: legacy compatibility behaviour for vehicles without defined heating power source
|
||||||
|
if( ( EnginePowerSource.SourceType == TPowerSource::CurrentCollector )
|
||||||
|
&& ( HeatingPowerSource.SourceType == TPowerSource::NotDefined ) ) {
|
||||||
|
HeatingPowerSource.SourceType = TPowerSource::Main;
|
||||||
|
}
|
||||||
|
if( ( HeatingPowerSource.SourceType == TPowerSource::NotDefined )
|
||||||
|
&& ( HeatingPower > 0 ) ) {
|
||||||
|
HeatingPowerSource.SourceType = TPowerSource::PowerCable;
|
||||||
|
HeatingPowerSource.PowerType = TPowerType::ElectricPower;
|
||||||
|
}
|
||||||
|
|
||||||
// checking ready flag
|
// checking ready flag
|
||||||
// to dac potem do init
|
// to dac potem do init
|
||||||
if( ReadyFlag ) // gotowy do drogi
|
if( ReadyFlag ) // gotowy do drogi
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ TModelsManager::LoadModel(std::string const &Name, bool dynamic) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TModel3d *
|
TModel3d *
|
||||||
TModelsManager::GetModel(std::string const &Name, bool const Dynamic)
|
TModelsManager::GetModel(std::string const &Name, bool const Dynamic, bool const Logerrors )
|
||||||
{ // model może być we wpisie "node...model" albo "node...dynamic", a także być dodatkowym w dynamic
|
{ // model może być we wpisie "node...model" albo "node...dynamic", a także być dodatkowym w dynamic
|
||||||
// (kabina, wnętrze, ładunek)
|
// (kabina, wnętrze, ładunek)
|
||||||
// dla "node...dynamic" mamy podaną ścieżkę w "\dynamic\" i musi być co najmniej 1 poziom, zwkle
|
// dla "node...dynamic" mamy podaną ścieżkę w "\dynamic\" i musi być co najmniej 1 poziom, zwkle
|
||||||
@@ -106,7 +106,9 @@ TModelsManager::GetModel(std::string const &Name, bool const Dynamic)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// there's nothing matching in the databank nor on the disk, report failure...
|
// there's nothing matching in the databank nor on the disk, report failure...
|
||||||
|
if( Logerrors ) {
|
||||||
ErrorLog( "Bad file: failed do locate 3d model file \"" + filename + "\"", logtype::file );
|
ErrorLog( "Bad file: failed do locate 3d model file \"" + filename + "\"", logtype::file );
|
||||||
|
}
|
||||||
// ...and link it with the error model slot
|
// ...and link it with the error model slot
|
||||||
m_modelsmap.emplace( filename, null_handle );
|
m_modelsmap.emplace( filename, null_handle );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ private:
|
|||||||
class TModelsManager {
|
class TModelsManager {
|
||||||
public:
|
public:
|
||||||
// McZapkie: dodalem sciezke, notabene Path!=Patch :)
|
// McZapkie: dodalem sciezke, notabene Path!=Patch :)
|
||||||
static TModel3d *GetModel( std::string const &Name, bool dynamic = false );
|
static TModel3d *GetModel( std::string const &Name, bool const dynamic = false, bool const Logerrors = true );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types:
|
// types:
|
||||||
|
|||||||
@@ -529,7 +529,7 @@ glm::vec3
|
|||||||
TTraction::wire_color() const {
|
TTraction::wire_color() const {
|
||||||
|
|
||||||
glm::vec3 color;
|
glm::vec3 color;
|
||||||
if( !DebugModeFlag || GfxRenderer.settings.force_normal_traction_render )
|
if( !GfxRenderer.settings.traction_debug )
|
||||||
{
|
{
|
||||||
switch( Material ) { // Ra: kolory podzieliłem przez 2, bo po zmianie ambient za jasne były
|
switch( Material ) { // Ra: kolory podzieliłem przez 2, bo po zmianie ambient za jasne były
|
||||||
// trzeba uwzględnić kierunek świecenia Słońca - tylko ze Słońcem widać kolor
|
// trzeba uwzględnić kierunek świecenia Słońca - tylko ze Słońcem widać kolor
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
class TTractionPowerSource : public scene::basic_node {
|
class TTractionPowerSource : public scene::basic_node {
|
||||||
|
|
||||||
|
friend class debug_panel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructor
|
// constructor
|
||||||
TTractionPowerSource( scene::node_data const &Nodedata );
|
TTractionPowerSource( scene::node_data const &Nodedata );
|
||||||
|
|||||||
58
Train.cpp
58
Train.cpp
@@ -17,8 +17,9 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "simulation.h"
|
#include "simulation.h"
|
||||||
#include "Camera.h"
|
#include "Event.h"
|
||||||
#include "simulationtime.h"
|
#include "simulationtime.h"
|
||||||
|
#include "Camera.h"
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
#include "MdlMngr.h"
|
#include "MdlMngr.h"
|
||||||
#include "Model3d.h"
|
#include "Model3d.h"
|
||||||
@@ -339,6 +340,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
|
|||||||
{ user_command::radiochanneldecrease, &TTrain::OnCommand_radiochanneldecrease },
|
{ user_command::radiochanneldecrease, &TTrain::OnCommand_radiochanneldecrease },
|
||||||
{ user_command::radiostopsend, &TTrain::OnCommand_radiostopsend },
|
{ user_command::radiostopsend, &TTrain::OnCommand_radiostopsend },
|
||||||
{ user_command::radiostoptest, &TTrain::OnCommand_radiostoptest },
|
{ user_command::radiostoptest, &TTrain::OnCommand_radiostoptest },
|
||||||
|
{ user_command::radiocall3send, &TTrain::OnCommand_radiocall3send },
|
||||||
{ user_command::cabchangeforward, &TTrain::OnCommand_cabchangeforward },
|
{ user_command::cabchangeforward, &TTrain::OnCommand_cabchangeforward },
|
||||||
{ user_command::cabchangebackward, &TTrain::OnCommand_cabchangebackward },
|
{ user_command::cabchangebackward, &TTrain::OnCommand_cabchangebackward },
|
||||||
{ user_command::generictoggle0, &TTrain::OnCommand_generictoggle },
|
{ user_command::generictoggle0, &TTrain::OnCommand_generictoggle },
|
||||||
@@ -452,6 +454,8 @@ dictionary_source *TTrain::GetTrainState() {
|
|||||||
// basic systems state data
|
// basic systems state data
|
||||||
dict->insert( "battery", mvControlled->Battery );
|
dict->insert( "battery", mvControlled->Battery );
|
||||||
dict->insert( "linebreaker", mvControlled->Mains );
|
dict->insert( "linebreaker", mvControlled->Mains );
|
||||||
|
dict->insert( "main_init", ( mvControlled->MainsInitTimeCountdown < mvControlled->MainsInitTime ) && ( mvControlled->MainsInitTimeCountdown > 0.0 ) );
|
||||||
|
dict->insert( "main_ready", ( false == mvControlled->Mains ) && ( fHVoltage > 0.0 ) && ( mvControlled->MainsInitTimeCountdown <= 0.0 ) );
|
||||||
dict->insert( "converter", mvControlled->ConverterFlag );
|
dict->insert( "converter", mvControlled->ConverterFlag );
|
||||||
dict->insert( "converter_overload", mvControlled->ConvOvldFlag );
|
dict->insert( "converter_overload", mvControlled->ConvOvldFlag );
|
||||||
dict->insert( "compress", mvControlled->CompressorFlag );
|
dict->insert( "compress", mvControlled->CompressorFlag );
|
||||||
@@ -4718,10 +4722,10 @@ void TTrain::OnCommand_doorcloseall( TTrain *Train, command_data const &Command
|
|||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
|
|
||||||
if( Train->mvOccupied->Doors.has_autowarning ) {
|
if( Train->mvOccupied->Doors.has_autowarning ) {
|
||||||
// automatic departure signal delays actual door closing until the button is released
|
|
||||||
Train->mvOccupied->signal_departure( true );
|
Train->mvOccupied->signal_departure( true );
|
||||||
}
|
}
|
||||||
else {
|
if( Train->ggDoorAllOffButton.type() != TGaugeType::push_delayed ) {
|
||||||
|
// delays the action until the button is released
|
||||||
Train->mvOccupied->OperateDoors( side::right, false );
|
Train->mvOccupied->OperateDoors( side::right, false );
|
||||||
Train->mvOccupied->OperateDoors( side::left, false );
|
Train->mvOccupied->OperateDoors( side::left, false );
|
||||||
}
|
}
|
||||||
@@ -4732,10 +4736,10 @@ void TTrain::OnCommand_doorcloseall( TTrain *Train, command_data const &Command
|
|||||||
Train->ggDoorAllOffButton.UpdateValue( 1.0, Train->dsbSwitch );
|
Train->ggDoorAllOffButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||||
}
|
}
|
||||||
else if( Command.action == GLFW_RELEASE ) {
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
// release the button
|
|
||||||
if( Train->mvOccupied->Doors.has_autowarning ) {
|
if( Train->mvOccupied->Doors.has_autowarning ) {
|
||||||
// automatic departure signal delays actual door closing until the button is released
|
|
||||||
Train->mvOccupied->signal_departure( false );
|
Train->mvOccupied->signal_departure( false );
|
||||||
|
}
|
||||||
|
if( Train->ggDoorAllOffButton.type() == TGaugeType::push_delayed ) {
|
||||||
// now we can actually close the door
|
// now we can actually close the door
|
||||||
Train->mvOccupied->OperateDoors( side::right, false );
|
Train->mvOccupied->OperateDoors( side::right, false );
|
||||||
Train->mvOccupied->OperateDoors( side::left, false );
|
Train->mvOccupied->OperateDoors( side::left, false );
|
||||||
@@ -5011,6 +5015,7 @@ void TTrain::OnCommand_radiostoptest( TTrain *Train, command_data const &Command
|
|||||||
|
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
if( ( Train->RadioChannel() == 10 )
|
if( ( Train->RadioChannel() == 10 )
|
||||||
|
&& ( true == Train->mvOccupied->Radio )
|
||||||
&& ( Train->mvControlled->Battery || Train->mvControlled->ConverterFlag ) ) {
|
&& ( Train->mvControlled->Battery || Train->mvControlled->ConverterFlag ) ) {
|
||||||
Train->Dynamic()->RadioStop();
|
Train->Dynamic()->RadioStop();
|
||||||
}
|
}
|
||||||
@@ -5023,6 +5028,23 @@ void TTrain::OnCommand_radiostoptest( TTrain *Train, command_data const &Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TTrain::OnCommand_radiocall3send( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
|
if( Command.action == GLFW_PRESS ) {
|
||||||
|
if( ( Train->RadioChannel() != 10 )
|
||||||
|
&& ( true == Train->mvOccupied->Radio )
|
||||||
|
&& ( Train->mvControlled->Battery || Train->mvControlled->ConverterFlag ) ) {
|
||||||
|
simulation::Events.queue_receivers( radio_message::call3, Train->Dynamic()->GetPosition() );
|
||||||
|
}
|
||||||
|
// visual feedback
|
||||||
|
Train->ggRadioCall3.UpdateValue( 1.0 );
|
||||||
|
}
|
||||||
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
|
// visual feedback
|
||||||
|
Train->ggRadioCall3.UpdateValue( 0.0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TTrain::OnCommand_cabchangeforward( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_cabchangeforward( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
@@ -5036,6 +5058,10 @@ void TTrain::OnCommand_cabchangeforward( TTrain *Train, command_data const &Comm
|
|||||||
1 );
|
1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// HACK: match consist door permit state with the preset in the active cab
|
||||||
|
if( Train->ggDoorPermitPresetButton.SubModel != nullptr ) {
|
||||||
|
Train->mvOccupied->ChangeDoorPermitPreset( 0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5052,6 +5078,10 @@ void TTrain::OnCommand_cabchangebackward( TTrain *Train, command_data const &Com
|
|||||||
1 );
|
1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// HACK: match consist door permit state with the preset in the active cab
|
||||||
|
if( Train->ggDoorPermitPresetButton.SubModel != nullptr ) {
|
||||||
|
Train->mvOccupied->ChangeDoorPermitPreset( 0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5098,10 +5128,11 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
if( ( ggMainButton.GetDesiredValue() > 0.95 )
|
if( ( ggMainButton.GetDesiredValue() > 0.95 )
|
||||||
|| ( ggMainOnButton.GetDesiredValue() > 0.95 ) ) {
|
|| ( ggMainOnButton.GetDesiredValue() > 0.95 ) ) {
|
||||||
// keep track of period the line breaker button is held down, to determine when/if circuit closes
|
// keep track of period the line breaker button is held down, to determine when/if circuit closes
|
||||||
if( ( fHVoltage > 0.5 * mvControlled->EnginePowerSource.MaxVoltage )
|
if( ( mvControlled->MainsInitTimeCountdown <= 0.0 )
|
||||||
|
&& ( ( fHVoltage > 0.5 * mvControlled->EnginePowerSource.MaxVoltage )
|
||||||
|| ( ( mvControlled->EngineType != TEngineType::ElectricSeriesMotor )
|
|| ( ( mvControlled->EngineType != TEngineType::ElectricSeriesMotor )
|
||||||
&& ( mvControlled->EngineType != TEngineType::ElectricInductionMotor )
|
&& ( mvControlled->EngineType != TEngineType::ElectricInductionMotor )
|
||||||
&& ( true == mvControlled->Battery ) ) ) {
|
&& ( true == mvControlled->Battery ) ) ) ) {
|
||||||
// prevent the switch from working if there's no power
|
// prevent the switch from working if there's no power
|
||||||
// TODO: consider whether it makes sense for diesel engines and such
|
// TODO: consider whether it makes sense for diesel engines and such
|
||||||
fMainRelayTimer += Deltatime;
|
fMainRelayTimer += Deltatime;
|
||||||
@@ -5626,9 +5657,10 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
|| (true == mvControlled->Mains) ) ?
|
|| (true == mvControlled->Mains) ) ?
|
||||||
true :
|
true :
|
||||||
false ) );
|
false ) );
|
||||||
// NOTE: 'off' variant uses the same test, but opposite resulting states
|
|
||||||
btLampkaWylSzybkiOff.Turn(
|
btLampkaWylSzybkiOff.Turn(
|
||||||
( ( ( m_linebreakerstate == 2 )
|
( ( ( mvControlled->MainsInitTimeCountdown > 0.0 )
|
||||||
|
|| ( fHVoltage == 0.0 )
|
||||||
|
|| ( m_linebreakerstate == 2 )
|
||||||
|| ( true == mvControlled->Mains ) ) ?
|
|| ( true == mvControlled->Mains ) ) ?
|
||||||
false :
|
false :
|
||||||
true ) );
|
true ) );
|
||||||
@@ -5860,7 +5892,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
auto const *mover { tmp->MoverParameters };
|
auto const *mover { tmp->MoverParameters };
|
||||||
|
|
||||||
btLampkaWylSzybkiB.Turn( mover->Mains );
|
btLampkaWylSzybkiB.Turn( mover->Mains );
|
||||||
btLampkaWylSzybkiBOff.Turn( false == mover->Mains );
|
btLampkaWylSzybkiBOff.Turn( ( false == mover->Mains ) && ( mover->MainsInitTimeCountdown <= 0.0 ) && ( fHVoltage != 0.0 ) );
|
||||||
|
|
||||||
btLampkaOporyB.Turn(mover->ResistorsFlagCheck());
|
btLampkaOporyB.Turn(mover->ResistorsFlagCheck());
|
||||||
btLampkaBezoporowaB.Turn(
|
btLampkaBezoporowaB.Turn(
|
||||||
@@ -6115,6 +6147,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
ggRadioChannelNext.Update();
|
ggRadioChannelNext.Update();
|
||||||
ggRadioStop.Update();
|
ggRadioStop.Update();
|
||||||
ggRadioTest.Update();
|
ggRadioTest.Update();
|
||||||
|
ggRadioCall3.Update();
|
||||||
ggDepartureSignalButton.Update();
|
ggDepartureSignalButton.Update();
|
||||||
|
|
||||||
ggPantFrontButton.Update();
|
ggPantFrontButton.Update();
|
||||||
@@ -7332,6 +7365,7 @@ void TTrain::clear_cab_controls()
|
|||||||
ggRadioChannelNext.Clear();
|
ggRadioChannelNext.Clear();
|
||||||
ggRadioStop.Clear();
|
ggRadioStop.Clear();
|
||||||
ggRadioTest.Clear();
|
ggRadioTest.Clear();
|
||||||
|
ggRadioCall3.Clear();
|
||||||
ggDoorLeftPermitButton.Clear();
|
ggDoorLeftPermitButton.Clear();
|
||||||
ggDoorRightPermitButton.Clear();
|
ggDoorRightPermitButton.Clear();
|
||||||
ggDoorPermitPresetButton.Clear();
|
ggDoorPermitPresetButton.Clear();
|
||||||
@@ -7649,7 +7683,7 @@ void TTrain::set_cab_controls( int const Cab ) {
|
|||||||
TimetableLightActive ?
|
TimetableLightActive ?
|
||||||
1.f :
|
1.f :
|
||||||
0.f ) );
|
0.f ) );
|
||||||
// doors
|
// doors permits
|
||||||
if( ggDoorLeftPermitButton.type() != TGaugeType::push ) {
|
if( ggDoorLeftPermitButton.type() != TGaugeType::push ) {
|
||||||
ggDoorLeftPermitButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::left : side::right ) ].open_permit ? 1.f : 0.f );
|
ggDoorLeftPermitButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::left : side::right ) ].open_permit ? 1.f : 0.f );
|
||||||
}
|
}
|
||||||
@@ -7657,6 +7691,7 @@ void TTrain::set_cab_controls( int const Cab ) {
|
|||||||
ggDoorRightPermitButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::right : side::left ) ].open_permit ? 1.f : 0.f );
|
ggDoorRightPermitButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::right : side::left ) ].open_permit ? 1.f : 0.f );
|
||||||
}
|
}
|
||||||
ggDoorPermitPresetButton.PutValue( mvOccupied->Doors.permit_preset );
|
ggDoorPermitPresetButton.PutValue( mvOccupied->Doors.permit_preset );
|
||||||
|
// door controls
|
||||||
ggDoorLeftButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::left : side::right ) ].is_closed ? 0.f : 1.f );
|
ggDoorLeftButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::left : side::right ) ].is_closed ? 0.f : 1.f );
|
||||||
ggDoorRightButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::right : side::left ) ].is_closed ? 0.f : 1.f );
|
ggDoorRightButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::right : side::left ) ].is_closed ? 0.f : 1.f );
|
||||||
// door lock
|
// door lock
|
||||||
@@ -8017,6 +8052,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
{ "radiochannelnext_sw:", ggRadioChannelNext },
|
{ "radiochannelnext_sw:", ggRadioChannelNext },
|
||||||
{ "radiostop_sw:", ggRadioStop },
|
{ "radiostop_sw:", ggRadioStop },
|
||||||
{ "radiotest_sw:", ggRadioTest },
|
{ "radiotest_sw:", ggRadioTest },
|
||||||
|
{ "radiocall3_sw:", ggRadioCall3 },
|
||||||
{ "pantfront_sw:", ggPantFrontButton },
|
{ "pantfront_sw:", ggPantFrontButton },
|
||||||
{ "pantrear_sw:", ggPantRearButton },
|
{ "pantrear_sw:", ggPantRearButton },
|
||||||
{ "pantfrontoff_sw:", ggPantFrontButtonOff },
|
{ "pantfrontoff_sw:", ggPantFrontButtonOff },
|
||||||
|
|||||||
2
Train.h
2
Train.h
@@ -342,6 +342,7 @@ class TTrain
|
|||||||
static void OnCommand_radiochanneldecrease( TTrain *Train, command_data const &Command );
|
static void OnCommand_radiochanneldecrease( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_radiostopsend( TTrain *Train, command_data const &Command );
|
static void OnCommand_radiostopsend( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_radiostoptest( TTrain *Train, command_data const &Command );
|
static void OnCommand_radiostoptest( TTrain *Train, command_data const &Command );
|
||||||
|
static void OnCommand_radiocall3send( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_cabchangeforward( TTrain *Train, command_data const &Command );
|
static void OnCommand_cabchangeforward( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_cabchangebackward( TTrain *Train, command_data const &Command );
|
static void OnCommand_cabchangebackward( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_generictoggle( TTrain *Train, command_data const &Command );
|
static void OnCommand_generictoggle( TTrain *Train, command_data const &Command );
|
||||||
@@ -412,6 +413,7 @@ public: // reszta może by?publiczna
|
|||||||
TGauge ggRadioChannelNext;
|
TGauge ggRadioChannelNext;
|
||||||
TGauge ggRadioTest;
|
TGauge ggRadioTest;
|
||||||
TGauge ggRadioStop;
|
TGauge ggRadioStop;
|
||||||
|
TGauge ggRadioCall3;
|
||||||
TGauge ggUpperLightButton;
|
TGauge ggUpperLightButton;
|
||||||
TGauge ggLeftLightButton;
|
TGauge ggLeftLightButton;
|
||||||
TGauge ggRightLightButton;
|
TGauge ggRightLightButton;
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
|
|||||||
{ // przesuwanie wózka po torach o odległość (fDistance), z wyzwoleniem eventów
|
{ // przesuwanie wózka po torach o odległość (fDistance), z wyzwoleniem eventów
|
||||||
// bPrimary=true - jest pierwszą osią w pojeździe, czyli generuje eventy i przepisuje pojazd
|
// bPrimary=true - jest pierwszą osią w pojeździe, czyli generuje eventy i przepisuje pojazd
|
||||||
// Ra: zwraca false, jeśli pojazd ma być usunięty
|
// Ra: zwraca false, jeśli pojazd ma być usunięty
|
||||||
auto const ismoving { ( std::abs( fDistance ) > 0.01 ) && ( Owner->GetVelocity() > 0.01 ) };
|
auto const ismoving { /* ( std::abs( fDistance ) > 0.01 ) && */ ( Owner->GetVelocity() > 0.01 ) };
|
||||||
fDistance *= fDirection; // dystans mnożnony przez kierunek
|
fDistance *= fDirection; // dystans mnożnony przez kierunek
|
||||||
double s; // roboczy dystans
|
double s; // roboczy dystans
|
||||||
double dir; // zapamiętany kierunek do sprawdzenia, czy się zmienił
|
double dir; // zapamiętany kierunek do sprawdzenia, czy się zmienił
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ commanddescription_sequence Commands_descriptions = {
|
|||||||
{ "radiochanneldecrease", command_target::vehicle, command_mode::oneoff },
|
{ "radiochanneldecrease", command_target::vehicle, command_mode::oneoff },
|
||||||
{ "radiostopsend", command_target::vehicle, command_mode::oneoff },
|
{ "radiostopsend", command_target::vehicle, command_mode::oneoff },
|
||||||
{ "radiostoptest", command_target::vehicle, command_mode::oneoff },
|
{ "radiostoptest", command_target::vehicle, command_mode::oneoff },
|
||||||
|
{ "radiocall3send", command_target::vehicle, command_mode::oneoff },
|
||||||
// TBD, TODO: make cab change controls entity-centric
|
// TBD, TODO: make cab change controls entity-centric
|
||||||
{ "cabchangeforward", command_target::vehicle, command_mode::oneoff },
|
{ "cabchangeforward", command_target::vehicle, command_mode::oneoff },
|
||||||
{ "cabchangebackward", command_target::vehicle, command_mode::oneoff },
|
{ "cabchangebackward", command_target::vehicle, command_mode::oneoff },
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ enum class user_command {
|
|||||||
radiochanneldecrease,
|
radiochanneldecrease,
|
||||||
radiostopsend,
|
radiostopsend,
|
||||||
radiostoptest,
|
radiostoptest,
|
||||||
|
radiocall3send,
|
||||||
cabchangeforward,
|
cabchangeforward,
|
||||||
cabchangebackward,
|
cabchangebackward,
|
||||||
|
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ driverkeyboard_input::default_bindings() {
|
|||||||
{ user_command::radiochanneldecrease, GLFW_KEY_R },
|
{ user_command::radiochanneldecrease, GLFW_KEY_R },
|
||||||
{ user_command::radiostopsend, GLFW_KEY_PAUSE | keymodifier::shift | keymodifier::control },
|
{ user_command::radiostopsend, GLFW_KEY_PAUSE | keymodifier::shift | keymodifier::control },
|
||||||
{ user_command::radiostoptest, GLFW_KEY_R | keymodifier::shift | keymodifier::control },
|
{ user_command::radiostoptest, GLFW_KEY_R | keymodifier::shift | keymodifier::control },
|
||||||
|
{ user_command::radiocall3send, GLFW_KEY_BACKSPACE },
|
||||||
{ user_command::cabchangeforward, GLFW_KEY_HOME },
|
{ user_command::cabchangeforward, GLFW_KEY_HOME },
|
||||||
{ user_command::cabchangebackward, GLFW_KEY_END },
|
{ user_command::cabchangebackward, GLFW_KEY_END },
|
||||||
// viewturn,
|
// viewturn,
|
||||||
|
|||||||
@@ -712,6 +712,9 @@ drivermouse_input::default_bindings() {
|
|||||||
{ "radiotest_sw:", {
|
{ "radiotest_sw:", {
|
||||||
user_command::radiostoptest,
|
user_command::radiostoptest,
|
||||||
user_command::none } },
|
user_command::none } },
|
||||||
|
{ "radiocall3_sw:", {
|
||||||
|
user_command::radiocall3send,
|
||||||
|
user_command::none } },
|
||||||
{ "pantfront_sw:", {
|
{ "pantfront_sw:", {
|
||||||
user_command::pantographtogglefront,
|
user_command::pantographtogglefront,
|
||||||
user_command::none } },
|
user_command::none } },
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ driver_ui::driver_ui() {
|
|||||||
m_scenariopanel.size_max = { Global.iWindowWidth * 0.95, Global.iWindowHeight * 0.95 };
|
m_scenariopanel.size_max = { Global.iWindowWidth * 0.95, Global.iWindowHeight * 0.95 };
|
||||||
|
|
||||||
m_timetablepanel.title = locale::strings[ locale::string::driver_timetable_header ];
|
m_timetablepanel.title = locale::strings[ locale::string::driver_timetable_header ];
|
||||||
m_timetablepanel.size_min = { 435, 110 };
|
m_timetablepanel.size_min = { 435, 70 };
|
||||||
m_timetablepanel.size_max = { 435, Global.iWindowHeight * 0.95 };
|
m_timetablepanel.size_max = { 435, Global.iWindowHeight * 0.95 };
|
||||||
|
|
||||||
m_transcriptspanel.title = locale::strings[ locale::string::driver_transcripts_header ];
|
m_transcriptspanel.title = locale::strings[ locale::string::driver_transcripts_header ];
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "simulationtime.h"
|
#include "simulationtime.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
|
#include "TractionPower.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "mtable.h"
|
#include "mtable.h"
|
||||||
#include "Train.h"
|
#include "Train.h"
|
||||||
@@ -265,23 +266,23 @@ timetable_panel::update() {
|
|||||||
auto const *table = owner->TrainTimetable();
|
auto const *table = owner->TrainTimetable();
|
||||||
if( table == nullptr ) { return; }
|
if( table == nullptr ) { return; }
|
||||||
|
|
||||||
{ // destination
|
// destination
|
||||||
|
{
|
||||||
auto textline = Bezogonkow( owner->Relation(), true );
|
auto textline = Bezogonkow( owner->Relation(), true );
|
||||||
if( false == textline.empty() ) {
|
if( false == textline.empty() ) {
|
||||||
textline += " (" + Bezogonkow( owner->TrainName(), true ) + ")";
|
textline += " (" + Bezogonkow( owner->TrainName(), true ) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
text_lines.emplace_back( textline, Global.UITextColor );
|
text_lines.emplace_back( textline, Global.UITextColor );
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // next station
|
if( false == is_expanded ) {
|
||||||
|
// next station
|
||||||
auto const nextstation = owner->NextStop();
|
auto const nextstation = owner->NextStop();
|
||||||
if( false == nextstation.empty() ) {
|
if( false == nextstation.empty() ) {
|
||||||
// jeśli jest podana relacja, to dodajemy punkt następnego zatrzymania
|
// jeśli jest podana relacja, to dodajemy punkt następnego zatrzymania
|
||||||
auto textline = " -> " + nextstation;
|
auto textline = " -> " + nextstation;
|
||||||
|
|
||||||
text_lines.emplace_back( textline, Global.UITextColor );
|
text_lines.emplace_back( textline, Global.UITextColor );
|
||||||
text_lines.emplace_back( "", Global.UITextColor );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +310,6 @@ timetable_panel::update() {
|
|||||||
static_cast<int>( consistlength ) );
|
static_cast<int>( consistlength ) );
|
||||||
|
|
||||||
text_lines.emplace_back( m_buffer.data(), Global.UITextColor );
|
text_lines.emplace_back( m_buffer.data(), Global.UITextColor );
|
||||||
text_lines.emplace_back( "", Global.UITextColor );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( 0 == table->StationCount ) {
|
if( 0 == table->StationCount ) {
|
||||||
@@ -377,24 +377,26 @@ timetable_panel::update() {
|
|||||||
candeparture ? readycolor : // czas minął i odjazd był, to nazwa stacji będzie na zielono
|
candeparture ? readycolor : // czas minął i odjazd był, to nazwa stacji będzie na zielono
|
||||||
isatpassengerstop ? waitcolor :
|
isatpassengerstop ? waitcolor :
|
||||||
Global.UITextColor ) };
|
Global.UITextColor ) };
|
||||||
|
auto const trackcount{ ( tableline->TrackNo == 1 ? u8" ┃ " : u8" ║ " ) };
|
||||||
m_tablelines.emplace_back(
|
m_tablelines.emplace_back(
|
||||||
( u8"│ " + vmax + u8" │ " + station + u8" │ " + arrival + u8" │ " + traveltime + u8" │" ),
|
( u8"│ " + vmax + u8" │ " + station + trackcount + arrival + u8" │ " + traveltime + u8" │" ),
|
||||||
linecolor );
|
linecolor );
|
||||||
m_tablelines.emplace_back(
|
m_tablelines.emplace_back(
|
||||||
( u8"│ │ " + location + tableline->StationWare + u8" │ " + departure + u8" │ │" ),
|
( u8"│ │ " + location + tableline->StationWare + trackcount + departure + u8" │ │" ),
|
||||||
linecolor );
|
linecolor );
|
||||||
// divider/footer
|
// divider/footer
|
||||||
if( i < table->StationCount ) {
|
if( i < table->StationCount ) {
|
||||||
auto const *nexttableline { tableline + 1 };
|
auto const *nexttableline { tableline + 1 };
|
||||||
if( tableline->vmax == nexttableline->vmax ) {
|
std::string const vmaxnext{ ( tableline->vmax == nexttableline->vmax ? u8"│ ├" : u8"├─────┼" ) };
|
||||||
m_tablelines.emplace_back( u8"│ ├────────────────────────────────────┼─────────┼─────┤", Global.UITextColor );
|
auto const trackcountnext{ ( nexttableline->TrackNo == 1 ? u8"╂" : u8"╫" ) };
|
||||||
|
m_tablelines.emplace_back(
|
||||||
|
vmaxnext + u8"────────────────────────────────────" + trackcountnext + u8"─────────┼─────┤",
|
||||||
|
Global.UITextColor );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_tablelines.emplace_back( u8"├─────┼────────────────────────────────────┼─────────┼─────┤", Global.UITextColor );
|
m_tablelines.emplace_back(
|
||||||
}
|
u8"└─────┴────────────────────────────────────┴─────────┴─────┘",
|
||||||
}
|
Global.UITextColor );
|
||||||
else {
|
|
||||||
m_tablelines.emplace_back( u8"└─────┴────────────────────────────────────┴─────────┴─────┘", Global.UITextColor );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -474,6 +476,7 @@ debug_panel::update() {
|
|||||||
m_scantablelines.clear();
|
m_scantablelines.clear();
|
||||||
m_scenariolines.clear();
|
m_scenariolines.clear();
|
||||||
m_eventqueuelines.clear();
|
m_eventqueuelines.clear();
|
||||||
|
m_powergridlines.clear();
|
||||||
m_cameralines.clear();
|
m_cameralines.clear();
|
||||||
m_rendererlines.clear();
|
m_rendererlines.clear();
|
||||||
|
|
||||||
@@ -483,6 +486,7 @@ debug_panel::update() {
|
|||||||
update_section_scantable( m_scantablelines );
|
update_section_scantable( m_scantablelines );
|
||||||
update_section_scenario( m_scenariolines );
|
update_section_scenario( m_scenariolines );
|
||||||
update_section_eventqueue( m_eventqueuelines );
|
update_section_eventqueue( m_eventqueuelines );
|
||||||
|
update_section_powergrid( m_powergridlines );
|
||||||
update_section_camera( m_cameralines );
|
update_section_camera( m_cameralines );
|
||||||
update_section_renderer( m_rendererlines );
|
update_section_renderer( m_rendererlines );
|
||||||
}
|
}
|
||||||
@@ -524,19 +528,17 @@ debug_panel::render() {
|
|||||||
// event queue filter
|
// event queue filter
|
||||||
ImGui::Checkbox( "By This Vehicle Only", &m_eventqueueactivevehicleonly );
|
ImGui::Checkbox( "By This Vehicle Only", &m_eventqueueactivevehicleonly );
|
||||||
}
|
}
|
||||||
|
if( true == render_section( "Power Grid", m_powergridlines ) ) {
|
||||||
|
// traction state debug
|
||||||
|
ImGui::Checkbox(
|
||||||
|
"Traction debug",
|
||||||
|
&GfxRenderer.settings.traction_debug );
|
||||||
|
}
|
||||||
render_section( "Camera", m_cameralines );
|
render_section( "Camera", m_cameralines );
|
||||||
render_section( "Gfx Renderer", m_rendererlines );
|
render_section( "Gfx Renderer", m_rendererlines );
|
||||||
// toggles
|
// toggles
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Checkbox( "Debug Mode", &DebugModeFlag );
|
ImGui::Checkbox( "Debug Mode", &DebugModeFlag );
|
||||||
if( DebugModeFlag )
|
|
||||||
{
|
|
||||||
ImGui::Indent();
|
|
||||||
ImGui::Checkbox(
|
|
||||||
"Draw normal traction",
|
|
||||||
&GfxRenderer.settings.force_normal_traction_render );
|
|
||||||
ImGui::Unindent();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
@@ -588,14 +590,17 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
|||||||
( mover.ConvOvldFlag ? '!' : '.' ),
|
( mover.ConvOvldFlag ? '!' : '.' ),
|
||||||
( mover.CompressorFlag ? 'C' : ( false == mover.CompressorAllowLocal ? '-' : ( ( mover.CompressorAllow || mover.CompressorStart == start_t::automatic ) ? 'c' : '.' ) ) ),
|
( mover.CompressorFlag ? 'C' : ( false == mover.CompressorAllowLocal ? '-' : ( ( mover.CompressorAllow || mover.CompressorStart == start_t::automatic ) ? 'c' : '.' ) ) ),
|
||||||
( mover.CompressorGovernorLock ? '!' : '.' ),
|
( mover.CompressorGovernorLock ? '!' : '.' ),
|
||||||
|
( mover.Heating ? 'H' : ( mover.HeatingAllow ? 'h' : '.' ) ),
|
||||||
std::string( isplayervehicle ? locale::strings[ locale::string::debug_vehicle_radio ] + ( mover.Radio ? std::to_string( m_input.train->RadioChannel() ) : "-" ) : "" ).c_str(),
|
std::string( isplayervehicle ? locale::strings[ locale::string::debug_vehicle_radio ] + ( mover.Radio ? std::to_string( m_input.train->RadioChannel() ) : "-" ) : "" ).c_str(),
|
||||||
std::string( isdieselenginepowered ? locale::strings[ locale::string::debug_vehicle_oilpressure ] + to_string( mover.OilPump.pressure, 2 ) : "" ).c_str(),
|
std::string( isdieselenginepowered ? locale::strings[ locale::string::debug_vehicle_oilpressure ] + to_string( mover.OilPump.pressure, 2 ) : "" ).c_str(),
|
||||||
// power transfers
|
// power transfers
|
||||||
mover.Couplers[ end::front ].power_high.voltage,
|
mover.Couplers[ end::front ].power_high.voltage,
|
||||||
mover.Couplers[ end::front ].power_high.current,
|
mover.Couplers[ end::front ].power_high.current,
|
||||||
std::string( mover.Couplers[ end::front ].power_high.local ? "" : "-" ).c_str(),
|
std::string( mover.Couplers[ end::front ].power_high.is_local ? "" : "-" ).c_str(),
|
||||||
std::string( vehicle.DirectionGet() ? ":<<:" : ":>>:" ).c_str(),
|
std::string( vehicle.DirectionGet() ? ":<<" : ":>>" ).c_str(),
|
||||||
std::string( mover.Couplers[ end::rear ].power_high.local ? "" : "-" ).c_str(),
|
mover.Voltage,
|
||||||
|
std::string( vehicle.DirectionGet() ? "<<:" : ">>:" ).c_str(),
|
||||||
|
std::string( mover.Couplers[ end::rear ].power_high.is_local ? "" : "-" ).c_str(),
|
||||||
mover.Couplers[ end::rear ].power_high.voltage,
|
mover.Couplers[ end::rear ].power_high.voltage,
|
||||||
mover.Couplers[ end::rear ].power_high.current );
|
mover.Couplers[ end::rear ].power_high.current );
|
||||||
|
|
||||||
@@ -805,7 +810,11 @@ debug_panel::update_section_engine( std::vector<text_line> &Output ) {
|
|||||||
{ "hTCTI: ", mover.hydro_TC_TorqueIn },
|
{ "hTCTI: ", mover.hydro_TC_TorqueIn },
|
||||||
{ "hTCTO: ", mover.hydro_TC_TorqueOut },
|
{ "hTCTO: ", mover.hydro_TC_TorqueOut },
|
||||||
{ "hTCfl: ", mover.hydro_TC_Fill },
|
{ "hTCfl: ", mover.hydro_TC_Fill },
|
||||||
{ "hTCLR: ", mover.hydro_TC_LockupRate } };
|
{ "hRtFl: ", mover.hydro_R_Fill } ,
|
||||||
|
{ " hRtn: ", mover.hydro_R_n } ,
|
||||||
|
{ "hRtTq: ", mover.hydro_R_Torque }
|
||||||
|
|
||||||
|
};
|
||||||
for( auto const ¶meter : hydrovalues ) {
|
for( auto const ¶meter : hydrovalues ) {
|
||||||
parameterstext += "\n" + parameter.first + to_string( parameter.second, 2, 9 );
|
parameterstext += "\n" + parameter.first + to_string( parameter.second, 2, 9 );
|
||||||
}
|
}
|
||||||
@@ -890,7 +899,10 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
|
|||||||
+ "\n brake threshold: " + to_string( mechanik.fAccThreshold, 2 )
|
+ "\n brake threshold: " + to_string( mechanik.fAccThreshold, 2 )
|
||||||
+ ", delays: " + to_string( mechanik.fBrake_a0[ 0 ], 2 )
|
+ ", delays: " + to_string( mechanik.fBrake_a0[ 0 ], 2 )
|
||||||
+ "+" + to_string( mechanik.fBrake_a1[ 0 ], 2 )
|
+ "+" + to_string( mechanik.fBrake_a1[ 0 ], 2 )
|
||||||
+ "\n virtual brake position: " + to_string(mechanik.BrakeCtrlPosition, 2);
|
+ "\n virtual brake position: " + to_string(mechanik.BrakeCtrlPosition, 2)
|
||||||
|
+ "\n desired diesel percentage: " + to_string(mechanik.DizelPercentage, 0)
|
||||||
|
+ "/" + to_string(mechanik.DizelPercentage_Speed, 0)
|
||||||
|
+ "/" + to_string(100.4*mechanik.mvControlling->eimic_real, 0);
|
||||||
|
|
||||||
Output.emplace_back( textline, Global.UITextColor );
|
Output.emplace_back( textline, Global.UITextColor );
|
||||||
|
|
||||||
@@ -988,6 +1000,46 @@ debug_panel::update_section_eventqueue( std::vector<text_line> &Output ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
debug_panel::update_section_powergrid( std::vector<text_line> &Output ) {
|
||||||
|
|
||||||
|
auto const lowpowercolor { glm::vec4( 164.0f / 255.0f, 132.0f / 255.0f, 84.0f / 255.0f, 1.f ) };
|
||||||
|
auto const nopowercolor { glm::vec4( 164.0f / 255.0f, 84.0f / 255.0f, 84.0f / 255.0f, 1.f ) };
|
||||||
|
|
||||||
|
Output.emplace_back( "Name: Output: Timeout:", Global.UITextColor );
|
||||||
|
|
||||||
|
std::string textline;
|
||||||
|
|
||||||
|
for( auto const *powerstation : simulation::Powergrid.sequence() ) {
|
||||||
|
|
||||||
|
if( true == powerstation->bSection ) { continue; }
|
||||||
|
|
||||||
|
auto const name { (
|
||||||
|
powerstation->m_name.empty() ?
|
||||||
|
"(unnamed)" :
|
||||||
|
powerstation->m_name )
|
||||||
|
+ " " };
|
||||||
|
|
||||||
|
textline =
|
||||||
|
name.substr( 0, 20 )
|
||||||
|
+ " " + to_string( powerstation->OutputVoltage, 0, 5 )
|
||||||
|
+ " " + to_string( powerstation->FuseTimer, 1, 12 )
|
||||||
|
+ ( powerstation->FuseCounter == 0 ?
|
||||||
|
"" :
|
||||||
|
" (x" + to_string( powerstation->FuseCounter ) + ")" );
|
||||||
|
|
||||||
|
Output.emplace_back(
|
||||||
|
textline,
|
||||||
|
( ( powerstation->FastFuse || powerstation->SlowFuse ) ? nopowercolor :
|
||||||
|
powerstation->OutputVoltage < ( 0.8 * powerstation->NominalVoltage ) ? lowpowercolor :
|
||||||
|
Global.UITextColor ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Output.size() == 1 ) {
|
||||||
|
Output.front().data = "(no power stations)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
debug_panel::update_section_camera( std::vector<text_line> &Output ) {
|
debug_panel::update_section_camera( std::vector<text_line> &Output ) {
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ private:
|
|||||||
void update_section_scantable( std::vector<text_line> &Output );
|
void update_section_scantable( std::vector<text_line> &Output );
|
||||||
void update_section_scenario( std::vector<text_line> &Output );
|
void update_section_scenario( std::vector<text_line> &Output );
|
||||||
void update_section_eventqueue( std::vector<text_line> &Output );
|
void update_section_eventqueue( std::vector<text_line> &Output );
|
||||||
|
void update_section_powergrid( std::vector<text_line> &Output );
|
||||||
void update_section_camera( std::vector<text_line> &Output );
|
void update_section_camera( std::vector<text_line> &Output );
|
||||||
void update_section_renderer( std::vector<text_line> &Output );
|
void update_section_renderer( std::vector<text_line> &Output );
|
||||||
// section update helpers
|
// section update helpers
|
||||||
@@ -105,6 +106,7 @@ private:
|
|||||||
m_cameralines,
|
m_cameralines,
|
||||||
m_scenariolines,
|
m_scenariolines,
|
||||||
m_eventqueuelines,
|
m_eventqueuelines,
|
||||||
|
m_powergridlines,
|
||||||
m_rendererlines;
|
m_rendererlines;
|
||||||
int tprev { 0 }; // poprzedni czas
|
int tprev { 0 }; // poprzedni czas
|
||||||
double VelPrev { 0.0 }; // poprzednia prędkość
|
double VelPrev { 0.0 }; // poprzednia prędkość
|
||||||
|
|||||||
@@ -549,6 +549,7 @@ void TTrainParameters::serialize( dictionary_source *Output ) const {
|
|||||||
Output->insert( ( stationlabel + "am" ), timetableline.Am );
|
Output->insert( ( stationlabel + "am" ), timetableline.Am );
|
||||||
Output->insert( ( stationlabel + "dh" ), timetableline.Dh );
|
Output->insert( ( stationlabel + "dh" ), timetableline.Dh );
|
||||||
Output->insert( ( stationlabel + "dm" ), timetableline.Dm );
|
Output->insert( ( stationlabel + "dm" ), timetableline.Dm );
|
||||||
|
Output->insert( ( stationlabel + "tracks" ), timetableline.TrackNo );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
99
renderer.cpp
99
renderer.cpp
@@ -496,10 +496,10 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
|
|
||||||
// run shadowmaps pass before color
|
// run shadowmaps pass before color
|
||||||
Timer::subsystem.gfx_shadows.start();
|
Timer::subsystem.gfx_shadows.start();
|
||||||
Render_pass( rendermode::shadows );
|
|
||||||
if( false == FreeFlyModeFlag ) {
|
if( false == FreeFlyModeFlag ) {
|
||||||
Render_pass( rendermode::cabshadows );
|
Render_pass( rendermode::cabshadows );
|
||||||
}
|
}
|
||||||
|
Render_pass( rendermode::shadows );
|
||||||
Timer::subsystem.gfx_shadows.stop();
|
Timer::subsystem.gfx_shadows.stop();
|
||||||
m_debugtimestext += "shadows: " + to_string( Timer::subsystem.gfx_shadows.average(), 2 ) + " msec (" + std::to_string( m_cellqueue.size() ) + " sectors)\n";
|
m_debugtimestext += "shadows: " + to_string( Timer::subsystem.gfx_shadows.average(), 2 ) + " msec (" + std::to_string( m_cellqueue.size() ) + " sectors)\n";
|
||||||
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
||||||
@@ -689,7 +689,6 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
// setup
|
// setup
|
||||||
::glEnable( GL_POLYGON_OFFSET_FILL ); // alleviate depth-fighting
|
::glEnable( GL_POLYGON_OFFSET_FILL ); // alleviate depth-fighting
|
||||||
::glPolygonOffset( 1.f, 1.f );
|
::glPolygonOffset( 1.f, 1.f );
|
||||||
::glDisable( GL_CULL_FACE );
|
|
||||||
|
|
||||||
::glBindFramebufferEXT( GL_FRAMEBUFFER, m_cabshadowframebuffer );
|
::glBindFramebufferEXT( GL_FRAMEBUFFER, m_cabshadowframebuffer );
|
||||||
::glViewport( 0, 0, m_shadowbuffersize / 2, m_shadowbuffersize / 2 );
|
::glViewport( 0, 0, m_shadowbuffersize / 2, m_shadowbuffersize / 2 );
|
||||||
@@ -712,6 +711,11 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
#else
|
#else
|
||||||
setup_units( false, false, false );
|
setup_units( false, false, false );
|
||||||
#endif
|
#endif
|
||||||
|
::glDisable( GL_CULL_FACE );
|
||||||
|
|
||||||
|
if( Global.RenderCabShadowsRange > 0 ) {
|
||||||
|
Render( simulation::Region );
|
||||||
|
}
|
||||||
Render_cab( simulation::Train->Dynamic(), 0.f, false );
|
Render_cab( simulation::Train->Dynamic(), 0.f, false );
|
||||||
Render_cab( simulation::Train->Dynamic(), 0.f, true );
|
Render_cab( simulation::Train->Dynamic(), 0.f, true );
|
||||||
m_cabshadowpass = m_renderpass;
|
m_cabshadowpass = m_renderpass;
|
||||||
@@ -856,7 +860,7 @@ opengl_renderer::setup_pass( renderpass_config &Config, rendermode const Mode, f
|
|||||||
switch( Mode ) {
|
switch( Mode ) {
|
||||||
case rendermode::color: { Config.draw_range = Global.BaseDrawRange; break; }
|
case rendermode::color: { Config.draw_range = Global.BaseDrawRange; break; }
|
||||||
case rendermode::shadows: { Config.draw_range = Global.BaseDrawRange * 0.5f; break; }
|
case rendermode::shadows: { Config.draw_range = Global.BaseDrawRange * 0.5f; break; }
|
||||||
case rendermode::cabshadows: { Config.draw_range = simulation::Train->Occupied()->Dim.L; break; }
|
case rendermode::cabshadows: { Config.draw_range = ( Global.RenderCabShadowsRange > 0 ? clamp( Global.RenderCabShadowsRange, 5, 100 ) : simulation::Train->Occupied()->Dim.L ); break; }
|
||||||
case rendermode::reflections: { Config.draw_range = Global.BaseDrawRange; break; }
|
case rendermode::reflections: { Config.draw_range = Global.BaseDrawRange; break; }
|
||||||
case rendermode::pickcontrols: { Config.draw_range = 50.f; break; }
|
case rendermode::pickcontrols: { Config.draw_range = 50.f; break; }
|
||||||
case rendermode::pickscenery: { Config.draw_range = Global.BaseDrawRange * 0.5f; break; }
|
case rendermode::pickscenery: { Config.draw_range = Global.BaseDrawRange * 0.5f; break; }
|
||||||
@@ -1746,6 +1750,7 @@ opengl_renderer::Render( scene::basic_region *Region ) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case rendermode::shadows:
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows:
|
||||||
case rendermode::pickscenery: {
|
case rendermode::pickscenery: {
|
||||||
// these render modes don't bother with lights
|
// these render modes don't bother with lights
|
||||||
Render( std::begin( m_sectionqueue ), std::end( m_sectionqueue ) );
|
Render( std::begin( m_sectionqueue ), std::end( m_sectionqueue ) );
|
||||||
@@ -1776,7 +1781,8 @@ opengl_renderer::Render( section_sequence::iterator First, section_sequence::ite
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows: {
|
||||||
// experimental, for shadows render both back and front faces, to supply back faces of the 'forest strips'
|
// experimental, for shadows render both back and front faces, to supply back faces of the 'forest strips'
|
||||||
::glDisable( GL_CULL_FACE );
|
::glDisable( GL_CULL_FACE );
|
||||||
break; }
|
break; }
|
||||||
@@ -1799,6 +1805,7 @@ opengl_renderer::Render( section_sequence::iterator First, section_sequence::ite
|
|||||||
case rendermode::color:
|
case rendermode::color:
|
||||||
case rendermode::reflections:
|
case rendermode::reflections:
|
||||||
case rendermode::shadows:
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows:
|
||||||
case rendermode::pickscenery: {
|
case rendermode::pickscenery: {
|
||||||
if( false == section->m_shapes.empty() ) {
|
if( false == section->m_shapes.empty() ) {
|
||||||
// since all shapes of the section share center point we can optimize out a few calls here
|
// since all shapes of the section share center point we can optimize out a few calls here
|
||||||
@@ -1822,6 +1829,7 @@ opengl_renderer::Render( section_sequence::iterator First, section_sequence::ite
|
|||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::color:
|
case rendermode::color:
|
||||||
case rendermode::shadows:
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows:
|
||||||
case rendermode::pickscenery: {
|
case rendermode::pickscenery: {
|
||||||
for( auto &cell : section->m_cells ) {
|
for( auto &cell : section->m_cells ) {
|
||||||
if( ( true == cell.m_active )
|
if( ( true == cell.m_active )
|
||||||
@@ -1845,7 +1853,8 @@ opengl_renderer::Render( section_sequence::iterator First, section_sequence::ite
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows: {
|
||||||
// restore standard face cull mode
|
// restore standard face cull mode
|
||||||
::glEnable( GL_CULL_FACE );
|
::glEnable( GL_CULL_FACE );
|
||||||
break; }
|
break; }
|
||||||
@@ -1932,6 +1941,22 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case rendermode::cabshadows: {
|
||||||
|
// since all shapes of the section share center point we can optimize out a few calls here
|
||||||
|
::glPushMatrix();
|
||||||
|
auto const originoffset { cell->m_area.center - m_renderpass.camera.position() };
|
||||||
|
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||||
|
|
||||||
|
// render
|
||||||
|
// opaque non-instanced shapes
|
||||||
|
for( auto const &shape : cell->m_shapesopaque ) { Render( shape, false ); }
|
||||||
|
// NOTE: tracks aren't likely to cast shadows into the cab, so we skip them in this pass
|
||||||
|
|
||||||
|
// post-render cleanup
|
||||||
|
::glPopMatrix();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case rendermode::pickscenery: {
|
case rendermode::pickscenery: {
|
||||||
// same procedure like with regular render, but editor-enabled nodes receive custom colour used for picking
|
// same procedure like with regular render, but editor-enabled nodes receive custom colour used for picking
|
||||||
// since all shapes of the section share center point we can optimize out a few calls here
|
// since all shapes of the section share center point we can optimize out a few calls here
|
||||||
@@ -1970,7 +1995,8 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
|
|||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::color:
|
case rendermode::color:
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows: {
|
||||||
// opaque parts of instanced models
|
// opaque parts of instanced models
|
||||||
for( auto *instance : cell->m_instancesopaque ) { Render( instance ); }
|
for( auto *instance : cell->m_instancesopaque ) { Render( instance ); }
|
||||||
// opaque parts of vehicles
|
// opaque parts of vehicles
|
||||||
@@ -2061,7 +2087,8 @@ opengl_renderer::Render( scene::shape_node const &Shape, bool const Ignorerange
|
|||||||
if( false == Ignorerange ) {
|
if( false == Ignorerange ) {
|
||||||
double distancesquared;
|
double distancesquared;
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows: {
|
||||||
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
||||||
distancesquared = Math3D::SquareMagnitude( ( data.area.center - Global.pCamera.Pos ) / Global.ZoomFactor ) / Global.fDistanceFactor;
|
distancesquared = Math3D::SquareMagnitude( ( data.area.center - Global.pCamera.Pos ) / Global.ZoomFactor ) / Global.fDistanceFactor;
|
||||||
break;
|
break;
|
||||||
@@ -2093,6 +2120,7 @@ opengl_renderer::Render( scene::shape_node const &Shape, bool const Ignorerange
|
|||||||
}
|
}
|
||||||
// pick modes are painted with custom colours, and shadow pass doesn't use any
|
// pick modes are painted with custom colours, and shadow pass doesn't use any
|
||||||
case rendermode::shadows:
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows:
|
||||||
case rendermode::pickscenery:
|
case rendermode::pickscenery:
|
||||||
case rendermode::pickcontrols:
|
case rendermode::pickcontrols:
|
||||||
default: {
|
default: {
|
||||||
@@ -2115,7 +2143,8 @@ opengl_renderer::Render( TAnimModel *Instance ) {
|
|||||||
|
|
||||||
double distancesquared;
|
double distancesquared;
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows: {
|
||||||
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
||||||
distancesquared = Math3D::SquareMagnitude( ( Instance->location() - Global.pCamera.Pos ) / Global.ZoomFactor ) / Global.fDistanceFactor;
|
distancesquared = Math3D::SquareMagnitude( ( Instance->location() - Global.pCamera.Pos ) / Global.ZoomFactor ) / Global.fDistanceFactor;
|
||||||
break;
|
break;
|
||||||
@@ -2129,6 +2158,11 @@ opengl_renderer::Render( TAnimModel *Instance ) {
|
|||||||
|| ( distancesquared >= Instance->m_rangesquaredmax ) ) {
|
|| ( distancesquared >= Instance->m_rangesquaredmax ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// crude way to reject early items too far to affect the output (mostly relevant for shadow passes)
|
||||||
|
auto const drawdistancethreshold{ m_renderpass.draw_range + 250 };
|
||||||
|
if( distancesquared > drawdistancethreshold * drawdistancethreshold ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::pickscenery: {
|
case rendermode::pickscenery: {
|
||||||
@@ -2161,17 +2195,23 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
|||||||
if( false == Dynamic->renderme ) {
|
if( false == Dynamic->renderme ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// debug data
|
|
||||||
++m_debugstats.dynamics;
|
|
||||||
|
|
||||||
// setup
|
|
||||||
TSubModel::iInstance = reinterpret_cast<std::uintptr_t>( Dynamic ); //żeby nie robić cudzych animacji
|
|
||||||
glm::dvec3 const originoffset = Dynamic->vPosition - m_renderpass.camera.position();
|
|
||||||
// lod visibility ranges are defined for base (x 1.0) viewing distance. for render we adjust them for actual range multiplier and zoom
|
// lod visibility ranges are defined for base (x 1.0) viewing distance. for render we adjust them for actual range multiplier and zoom
|
||||||
float squaredistance;
|
float squaredistance;
|
||||||
|
glm::dvec3 const originoffset = Dynamic->vPosition - m_renderpass.camera.position();
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows: {
|
||||||
squaredistance = glm::length2( glm::vec3{ glm::dvec3{ Dynamic->vPosition - Global.pCamera.Pos } } / Global.ZoomFactor ) / Global.fDistanceFactor;
|
squaredistance = glm::length2( glm::vec3{ glm::dvec3{ Dynamic->vPosition - Global.pCamera.Pos } } / Global.ZoomFactor ) / Global.fDistanceFactor;
|
||||||
|
if( false == FreeFlyModeFlag ) {
|
||||||
|
// filter out small details if we're in vehicle cab
|
||||||
|
squaredistance = std::max( 100.f * 100.f, squaredistance );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case rendermode::cabshadows: {
|
||||||
|
squaredistance = glm::length2( glm::vec3{ glm::dvec3{ Dynamic->vPosition - Global.pCamera.Pos } } / Global.ZoomFactor ) / Global.fDistanceFactor;
|
||||||
|
// filter out small details
|
||||||
|
squaredistance = std::max( 100.f * 100.f, squaredistance );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@@ -2179,6 +2219,18 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// crude way to reject early items too far to affect the output (mostly relevant for shadow passes)
|
||||||
|
auto const drawdistancethreshold { m_renderpass.draw_range + 250 };
|
||||||
|
if( squaredistance > drawdistancethreshold * drawdistancethreshold ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// debug data
|
||||||
|
++m_debugstats.dynamics;
|
||||||
|
|
||||||
|
// setup
|
||||||
|
TSubModel::iInstance = reinterpret_cast<std::uintptr_t>( Dynamic ); //żeby nie robić cudzych animacji
|
||||||
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
|
|
||||||
@@ -2233,7 +2285,8 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows: {
|
||||||
if( Dynamic->mdLowPolyInt ) {
|
if( Dynamic->mdLowPolyInt ) {
|
||||||
// low poly interior
|
// low poly interior
|
||||||
// if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
|
// if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
|
||||||
@@ -2781,7 +2834,8 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
|
|||||||
::glColor3fv( glm::value_ptr( colors::white ) );
|
::glColor3fv( glm::value_ptr( colors::white ) );
|
||||||
// setup
|
// setup
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows: {
|
||||||
// NOTE: roads-based platforms tend to miss parts of shadows if rendered with either back or front culling
|
// NOTE: roads-based platforms tend to miss parts of shadows if rendered with either back or front culling
|
||||||
::glDisable( GL_CULL_FACE );
|
::glDisable( GL_CULL_FACE );
|
||||||
break;
|
break;
|
||||||
@@ -2821,7 +2875,8 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows: {
|
||||||
if( ( std::abs( track->fTexHeight1 ) < 0.35f )
|
if( ( std::abs( track->fTexHeight1 ) < 0.35f )
|
||||||
|| ( track->iCategoryFlag != 2 ) ) {
|
|| ( track->iCategoryFlag != 2 ) ) {
|
||||||
// shadows are only calculated for high enough roads, typically meaning track platforms
|
// shadows are only calculated for high enough roads, typically meaning track platforms
|
||||||
@@ -2864,7 +2919,8 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows: {
|
||||||
if( ( std::abs( track->fTexHeight1 ) < 0.35f )
|
if( ( std::abs( track->fTexHeight1 ) < 0.35f )
|
||||||
|| ( ( track->iCategoryFlag == 1 )
|
|| ( ( track->iCategoryFlag == 1 )
|
||||||
&& ( track->eType != tt_Normal ) ) ) {
|
&& ( track->eType != tt_Normal ) ) ) {
|
||||||
@@ -2911,7 +2967,8 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows: {
|
||||||
if( ( std::abs( track->fTexHeight1 ) < 0.35f )
|
if( ( std::abs( track->fTexHeight1 ) < 0.35f )
|
||||||
|| ( ( track->iCategoryFlag == 1 )
|
|| ( ( track->iCategoryFlag == 1 )
|
||||||
&& ( track->eType != tt_Normal ) ) ) {
|
&& ( track->eType != tt_Normal ) ) ) {
|
||||||
@@ -2931,7 +2988,8 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
|
|||||||
}
|
}
|
||||||
// post-render reset
|
// post-render reset
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows: {
|
||||||
::glEnable( GL_CULL_FACE );
|
::glEnable( GL_CULL_FACE );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2950,7 +3008,8 @@ opengl_renderer::Render( TMemCell *Memcell ) {
|
|||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::color:
|
case rendermode::color:
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows:
|
||||||
|
case rendermode::cabshadows: {
|
||||||
::gluSphere( m_quadric, 0.35, 4, 2 );
|
::gluSphere( m_quadric, 0.35, 4, 2 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,8 +119,7 @@ public:
|
|||||||
/// Renderer runtime settings.
|
/// Renderer runtime settings.
|
||||||
struct Settings
|
struct Settings
|
||||||
{
|
{
|
||||||
/** Force normal render of traction, when user is in debug mode. */
|
bool traction_debug { false };
|
||||||
bool force_normal_traction_render { false };
|
|
||||||
} settings;
|
} settings;
|
||||||
// constructors
|
// constructors
|
||||||
opengl_renderer() = default;
|
opengl_renderer() = default;
|
||||||
|
|||||||
@@ -523,9 +523,12 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
scene::Groups.insert( scene::Groups.handle(), eventlauncher );
|
scene::Groups.insert( scene::Groups.handle(), eventlauncher );
|
||||||
|
if( false == eventlauncher->IsRadioActivated() ) {
|
||||||
|
// NOTE: radio-activated launchers due to potentially large activation radius are resolved on global level rather than put in a region cell
|
||||||
simulation::Region->insert( eventlauncher );
|
simulation::Region->insert( eventlauncher );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if( nodedata.type == "sound" ) {
|
else if( nodedata.type == "sound" ) {
|
||||||
|
|
||||||
auto *sound { deserialize_sound( Input, Scratchpad, nodedata ) };
|
auto *sound { deserialize_sound( Input, Scratchpad, nodedata ) };
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ init() {
|
|||||||
"Name: %s%s\nLoad: %.0f %s\nStatus: %s%s\nCouplers:\n front: %s\n rear: %s",
|
"Name: %s%s\nLoad: %.0f %s\nStatus: %s%s\nCouplers:\n front: %s\n rear: %s",
|
||||||
", owned by: ",
|
", owned by: ",
|
||||||
"none",
|
"none",
|
||||||
"Devices: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%s%s\nPower transfers: %.0f@%.0f%s%s%s%.0f@%.0f",
|
"Devices: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%s%s\nPower transfers: %.0f@%.0f%s%s[%.0f]%s%s%.0f@%.0f",
|
||||||
" radio: ",
|
" radio: ",
|
||||||
" oil pressure: ",
|
" oil pressure: ",
|
||||||
"Controllers:\n master: %d(%d), secondary: %s\nEngine output: %.1f, current: %.0f\nRevolutions:\n engine: %.0f, motors: %.0f\n engine fans: %.0f, motor fans: %.0f+%.0f, cooling fans: %.0f+%.0f",
|
"Controllers:\n master: %d(%d), secondary: %s\nEngine output: %.1f, current: %.0f\nRevolutions:\n engine: %.0f, motors: %.0f\n engine fans: %.0f, motor fans: %.0f+%.0f, cooling fans: %.0f+%.0f",
|
||||||
@@ -157,6 +157,7 @@ init() {
|
|||||||
"radio channel",
|
"radio channel",
|
||||||
"radiostop test",
|
"radiostop test",
|
||||||
"radiostop",
|
"radiostop",
|
||||||
|
"radio call 3",
|
||||||
"pantograph A",
|
"pantograph A",
|
||||||
"pantograph B",
|
"pantograph B",
|
||||||
"pantograph A",
|
"pantograph A",
|
||||||
@@ -236,7 +237,7 @@ init() {
|
|||||||
"Nazwa: %s%s\nLadunek: %.0f %s\nStatus: %s%s\nSprzegi:\n przedni: %s\n tylny: %s",
|
"Nazwa: %s%s\nLadunek: %.0f %s\nStatus: %s%s\nSprzegi:\n przedni: %s\n tylny: %s",
|
||||||
", wlasciciel: ",
|
", wlasciciel: ",
|
||||||
"wolny",
|
"wolny",
|
||||||
"Urzadzenia: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%s%s\nTransfer pradow: %.0f@%.0f%s%s%s%.0f@%.0f",
|
"Urzadzenia: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%s%s\nTransfer pradow: %.0f@%.0f%s%s[%.0f]%s%s%.0f@%.0f",
|
||||||
" radio: ",
|
" radio: ",
|
||||||
" cisn.oleju: ",
|
" cisn.oleju: ",
|
||||||
"Nastawniki:\n glowny: %d(%d), dodatkowy: %s\nMoc silnika: %.1f, prad silnika: %.0f\nObroty:\n silnik: %.0f, motory: %.0f\n went.silnika: %.0f, went.motorow: %.0f+%.0f, went.chlodnicy: %.0f+%.0f",
|
"Nastawniki:\n glowny: %d(%d), dodatkowy: %s\nMoc silnika: %.1f, prad silnika: %.0f\nObroty:\n silnik: %.0f, motory: %.0f\n went.silnika: %.0f, went.motorow: %.0f+%.0f, went.chlodnicy: %.0f+%.0f",
|
||||||
@@ -323,6 +324,7 @@ init() {
|
|||||||
"kanal radia",
|
"kanal radia",
|
||||||
"test radiostopu",
|
"test radiostopu",
|
||||||
"radiostop",
|
"radiostop",
|
||||||
|
"zew 3",
|
||||||
"pantograf A",
|
"pantograf A",
|
||||||
"pantograf B",
|
"pantograf B",
|
||||||
"pantograf A",
|
"pantograf A",
|
||||||
@@ -442,6 +444,7 @@ init() {
|
|||||||
"radiochannelnext_sw:",
|
"radiochannelnext_sw:",
|
||||||
"radiotest_sw:",
|
"radiotest_sw:",
|
||||||
"radiostop_sw:",
|
"radiostop_sw:",
|
||||||
|
"radiocall3_sw:",
|
||||||
"pantfront_sw:",
|
"pantfront_sw:",
|
||||||
"pantrear_sw:",
|
"pantrear_sw:",
|
||||||
"pantfrontoff_sw:",
|
"pantfrontoff_sw:",
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ enum string {
|
|||||||
cab_radiochannelnext_sw,
|
cab_radiochannelnext_sw,
|
||||||
cab_radiotest_sw,
|
cab_radiotest_sw,
|
||||||
cab_radiostop_sw,
|
cab_radiostop_sw,
|
||||||
|
cab_radiocall3_sw,
|
||||||
cab_pantfront_sw,
|
cab_pantfront_sw,
|
||||||
cab_pantrear_sw,
|
cab_pantrear_sw,
|
||||||
cab_pantfrontoff_sw,
|
cab_pantfrontoff_sw,
|
||||||
|
|||||||
Reference in New Issue
Block a user