16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-23 07:29:19 +02:00

basic power circuits simulation, vehicle device presence definition, automatic coupling tweaks, minor vehicle simulation logic enhancements, minor brake simulation logic fixes, pantograph control enhancements, ai logic enhancements

This commit is contained in:
tmj-fstate
2020-04-30 03:08:37 +02:00
parent 17b545e88a
commit c457ffe05d
14 changed files with 946 additions and 662 deletions

View File

@@ -2562,31 +2562,32 @@ bool TController::PrepareEngine()
mvControlling->FuelPumpSwitch( true ); mvControlling->FuelPumpSwitch( true );
} }
} }
if (mvControlling->EnginePowerSource.SourceType == TPowerSource::CurrentCollector) if( ( mvPantographUnit->EnginePowerSource.SourceType == TPowerSource::CurrentCollector )
{ // jeśli silnikowy jest pantografującym &&( mvPantographUnit->EnginePowerSource.CollectorParameters.CollectorsNo > 0 ) ) {
if (mvControlling->PantPress < 4.2) { // if our pantograph unit isn't a pantograph-devoid fallback
if (mvPantographUnit->PantPress < 4.2) {
// załączenie małej sprężarki // załączenie małej sprężarki
if( false == mvControlling->PantAutoValve ) { if( false == mvPantographUnit->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; mvPantographUnit->bPantKurek3 = false;
} }
mvControlling->PantCompFlag = true; // załączenie sprężarki pantografów mvPantographUnit->PantCompFlag = true; // załączenie sprężarki pantografów
} }
else { else {
// jeżeli jest wystarczające ciśnienie w pantografach // jeżeli jest wystarczające ciśnienie w pantografach
if ((!mvControlling->bPantKurek3) if ((!mvPantographUnit->bPantKurek3)
|| (mvControlling->PantPress <= mvControlling->ScndPipePress)) // kurek przełączony albo główna już pompuje || (mvPantographUnit->PantPress <= mvPantographUnit->ScndPipePress)) // kurek przełączony albo główna już pompuje
mvControlling->PantCompFlag = false; // sprężarkę pantografów można już wyłączyć mvPantographUnit->PantCompFlag = false; // sprężarkę pantografów można już wyłączyć
} }
if( ( fOverhead2 == -1.0 ) && ( iOverheadDown == 0 ) ) { if( ( fOverhead2 == -1.0 ) && ( iOverheadDown == 0 ) ) {
mvControlling->OperatePantographsValve( operation_t::enable ); mvOccupied->OperatePantographsValve( operation_t::enable );
mvControlling->OperatePantographValve( end::front, operation_t::enable ); mvOccupied->OperatePantographValve( end::front, operation_t::enable );
mvControlling->OperatePantographValve( end::rear, operation_t::enable ); mvOccupied->OperatePantographValve( end::rear, operation_t::enable );
} }
} }
} }
if ((mvControlling->PantographVoltage != 0.0) || voltfront || voltrear) if ((mvPantographUnit->PantographVoltage != 0.0) || voltfront || voltrear)
{ // najpierw ustalamy kierunek, jeśli nie został ustalony { // najpierw ustalamy kierunek, jeśli nie został ustalony
if( !iDirection ) { if( !iDirection ) {
// jeśli nie ma ustalonego kierunku // jeśli nie ma ustalonego kierunku
@@ -2594,7 +2595,7 @@ bool TController::PrepareEngine()
iDirection = mvOccupied->CabActive; // wg wybranej kabiny iDirection = mvOccupied->CabActive; // wg wybranej kabiny
if( !iDirection ) { if( !iDirection ) {
// jeśli nie ma ustalonego kierunku // jeśli nie ma ustalonego kierunku
if( ( mvControlling->PantographVoltage != 0.0 ) || voltfront || voltrear ) { if( ( mvPantographUnit->PantographVoltage != 0.0 ) || voltfront || voltrear ) {
if( mvOccupied->Couplers[ end::rear ].Connected == nullptr ) { if( mvOccupied->Couplers[ end::rear ].Connected == nullptr ) {
// jeśli z tyłu nie ma nic // jeśli z tyłu nie ma nic
iDirection = -1; // jazda w kierunku sprzęgu 1 iDirection = -1; // jazda w kierunku sprzęgu 1
@@ -2622,12 +2623,12 @@ bool TController::PrepareEngine()
} }
if (AIControllFlag) // jeśli prowadzi komputer if (AIControllFlag) // jeśli prowadzi komputer
{ // część wykonawcza dla sterowania przez komputer { // część wykonawcza dla sterowania przez komputer
if (mvControlling->ConvOvldFlag) if( IsAnyConverterOverloadRelayOpen ) {
{ // wywalił bezpiecznik nadmiarowy przetwornicy // wywalił bezpiecznik nadmiarowy przetwornicy
ZeroSpeed(); mvOccupied->ConverterSwitch( false );
mvControlling->ConvOvldFlag = false; // reset nadmiarowego mvOccupied->RelayReset( relay_t::primaryconverteroverload ); // reset nadmiarowego
} }
else if (false == IsLineBreakerClosed) { if (IsAnyLineBreakerOpen) {
ZeroSpeed(); ZeroSpeed();
if( mvOccupied->DirActive == 0 ) { if( mvOccupied->DirActive == 0 ) {
OrderDirectionChange( iDirection, mvOccupied ); OrderDirectionChange( iDirection, mvOccupied );
@@ -2641,19 +2642,21 @@ bool TController::PrepareEngine()
} }
} }
if( ( mvControlling->EnginePowerSource.SourceType != TPowerSource::CurrentCollector ) if( ( mvControlling->EnginePowerSource.SourceType != TPowerSource::CurrentCollector )
|| ( std::max( mvControlling->GetAnyTrainsetVoltage(), mvControlling->PantographVoltage ) > mvControlling->EnginePowerSource.CollectorParameters.MinV ) ) { || ( std::max( mvControlling->GetTrainsetHighVoltage(), mvControlling->PantographVoltage ) > mvControlling->EnginePowerSource.CollectorParameters.MinV ) ) {
mvControlling->MainSwitch( true ); mvOccupied->MainSwitch( true );
} }
} }
else { else {
mvControlling->ConverterSwitch( true ); if( false == IsAnyConverterOverloadRelayOpen ) {
// w EN57 sprężarka w ra jest zasilana z silnikowego mvOccupied->ConverterSwitch( true );
mvControlling->CompressorSwitch( true ); // w EN57 sprężarka w ra jest zasilana z silnikowego
// enable motor blowers mvOccupied->CompressorSwitch( true );
mvControlling->MotorBlowersSwitchOff( false, end::front ); // enable motor blowers
mvControlling->MotorBlowersSwitch( true, end::front ); mvOccupied->MotorBlowersSwitchOff( false, end::front );
mvControlling->MotorBlowersSwitchOff( false, end::rear ); mvOccupied->MotorBlowersSwitch( true, end::front );
mvControlling->MotorBlowersSwitch( true, end::rear ); mvOccupied->MotorBlowersSwitchOff( false, end::rear );
mvOccupied->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 ) );
@@ -2667,7 +2670,8 @@ bool TController::PrepareEngine()
if( lookup != brakepositions.end() ) { if( lookup != brakepositions.end() ) {
BrakeLevelSet( lookup->second ); // GBH BrakeLevelSet( lookup->second ); // GBH
} }
OK = ( VelforDriver == -1 ); OK = ( false == IsAnyConverterOverloadRelayOpen )
&& ( VelforDriver == -1 );
} }
} }
else else
@@ -2755,13 +2759,12 @@ bool TController::ReleaseEngine() {
// heating // heating
mvControlling->HeatingAllow = false; mvControlling->HeatingAllow = false;
// devices // devices
mvControlling->ConverterSwitch( false ); mvOccupied->ConverterSwitch( false );
// line breaker/engine // line breaker/engine
OK = mvControlling->MainSwitch( false ); OK = mvOccupied->MainSwitch( false );
if( mvControlling->EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) {
mvControlling->OperatePantographValve( end::front, operation_t::disable ); mvOccupied->OperatePantographValve( end::front, operation_t::disable );
mvControlling->OperatePantographValve( end::rear, operation_t::disable ); mvOccupied->OperatePantographValve( end::rear, operation_t::disable );
}
} }
else { else {
OK = true; OK = true;
@@ -3200,7 +3203,7 @@ bool TController::IncSpeed()
if (iOverheadZero) // jazda bezprądowa z poziomu toru ustawia bity if (iOverheadZero) // jazda bezprądowa z poziomu toru ustawia bity
return false; // to nici z ruszania return false; // to nici z ruszania
} }
if ((!mvControlling->FuseFlag) if ((!IsAnyMotorOverloadRelayOpen)
&&(!mvControlling->ControlPressureSwitch)) { &&(!mvControlling->ControlPressureSwitch)) {
if ((mvControlling->IsMainCtrlNoPowerPos()) if ((mvControlling->IsMainCtrlNoPowerPos())
|| (mvControlling->StLinFlag)) { // youBy polecił dodać 2012-09-08 v367 || (mvControlling->StLinFlag)) { // youBy polecił dodać 2012-09-08 v367
@@ -3303,7 +3306,7 @@ bool TController::IncSpeed()
mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania
break; break;
case TEngineType::Dumb: case TEngineType::Dumb:
if (!mvControlling->FuseFlag) if (!IsAnyMotorOverloadRelayOpen)
if (Ready || (iDrivigFlags & movePress)) //{(BrakePress<=0.01*MaxBrakePress)} if (Ready || (iDrivigFlags & movePress)) //{(BrakePress<=0.01*MaxBrakePress)}
{ {
OK = IncSpeedEIM(); OK = IncSpeedEIM();
@@ -3314,7 +3317,7 @@ bool TController::IncSpeed()
} }
break; break;
case TEngineType::DieselElectric: case TEngineType::DieselElectric:
if ((!mvControlling->FuseFlag) if ((!IsAnyMotorOverloadRelayOpen)
&&(!mvControlling->ControlPressureSwitch)) { &&(!mvControlling->ControlPressureSwitch)) {
if ((mvControlling->IsMainCtrlNoPowerPos()) || if ((mvControlling->IsMainCtrlNoPowerPos()) ||
(mvControlling->StLinFlag)) { // youBy polecił dodać 2012-09-08 v367 (mvControlling->StLinFlag)) { // youBy polecił dodać 2012-09-08 v367
@@ -3331,7 +3334,7 @@ bool TController::IncSpeed()
} }
break; break;
case TEngineType::ElectricInductionMotor: case TEngineType::ElectricInductionMotor:
if (!mvControlling->FuseFlag) if (!IsAnyMotorOverloadRelayOpen)
if (Ready || (iDrivigFlags & movePress) || (mvOccupied->ShuntMode)) //{(BrakePress<=0.01*MaxBrakePress)} if (Ready || (iDrivigFlags & movePress) || (mvOccupied->ShuntMode)) //{(BrakePress<=0.01*MaxBrakePress)}
{ {
OK = IncSpeedEIM(); OK = IncSpeedEIM();
@@ -3390,9 +3393,9 @@ bool TController::IncSpeed()
} }
if( false == mvControlling->Mains ) { if( false == mvControlling->Mains ) {
SpeedCntrl(0.0); SpeedCntrl(0.0);
mvControlling->MainSwitch( true ); mvOccupied->MainSwitch( true );
mvControlling->ConverterSwitch( true ); mvOccupied->ConverterSwitch( true );
mvControlling->CompressorSwitch( true ); mvOccupied->CompressorSwitch( true );
} }
break; break;
} }
@@ -4612,7 +4615,7 @@ TController::UpdateSituation(double dt) {
if( ( OrderCurrentGet() == Wait_for_orders ) if( ( OrderCurrentGet() == Wait_for_orders )
&& ( false == AIControllFlag ) && ( false == AIControllFlag )
&& ( false == iEngineActive ) && ( false == iEngineActive )
&& ( true == mvControlling->Battery ) ) { && ( true == mvOccupied->Power24vIsAvailable ) ) {
OrderNext( Prepare_engine ); OrderNext( Prepare_engine );
} }
@@ -4686,10 +4689,6 @@ TController::UpdateSituation(double dt) {
// ciężar razy składowa styczna grawitacji // ciężar razy składowa styczna grawitacji
fAccGravity -= vehicle->TotalMassxg * dy * ( p->DirectionGet() == iDirection ? 1 : -1 ); fAccGravity -= vehicle->TotalMassxg * dy * ( p->DirectionGet() == iDirection ? 1 : -1 );
} }
if( ( vehicle->Power > 0.01 ) // jeśli ma silnik
&& ( vehicle->FuseFlag ) ) { // wywalony nadmiarowy
Need_TryAgain = true; // reset jak przy wywaleniu nadmiarowego
}
// check door state // check door state
auto const switchsides { p->DirectionGet() != iDirection }; auto const switchsides { p->DirectionGet() != iDirection };
IsAnyDoorOpen[ side::right ] = IsAnyDoorOpen[ side::right ] =
@@ -4707,21 +4706,31 @@ TController::UpdateSituation(double dt) {
ConsistShade /= iVehicles; ConsistShade /= iVehicles;
// test state of main switch in all powered vehicles under control // test state of main switch in all powered vehicles under control
IsLineBreakerClosed = ( mvOccupied->Power > 0.01 ? mvOccupied->Mains : true ); IsAnyConverterOverloadRelayOpen = mvOccupied->ConvOvldFlag;
IsAnyMotorOverloadRelayOpen = mvOccupied->FuseFlag;
IsAnyGroundRelayOpen = !mvOccupied->GroundRelay;
IsAnyLineBreakerOpen = ( mvOccupied->Power > 0.01 ? !mvOccupied->Mains : false );
IsAnyCompressorEnabled = mvOccupied->CompressorAllow;
p = pVehicle; p = pVehicle;
while( ( true == IsLineBreakerClosed ) while( ( p = p->PrevC( coupling::control) ) != nullptr ) {
&& ( ( p = p->PrevC( coupling::control) ) != nullptr ) ) {
auto const *vehicle { p->MoverParameters }; auto const *vehicle { p->MoverParameters };
IsAnyConverterOverloadRelayOpen |= vehicle->ConvOvldFlag;
IsAnyMotorOverloadRelayOpen |= vehicle->FuseFlag;
IsAnyGroundRelayOpen |= !vehicle->GroundRelay;
IsAnyCompressorEnabled |= vehicle->CompressorAllow;
if( vehicle->Power > 0.01 ) { if( vehicle->Power > 0.01 ) {
IsLineBreakerClosed = ( IsLineBreakerClosed && vehicle->Mains ); IsAnyLineBreakerOpen |= !vehicle->Mains;
} }
} }
p = pVehicle; p = pVehicle;
while( ( true == IsLineBreakerClosed ) while( ( p = p->NextC( coupling::control ) ) != nullptr ) {
&& ( ( p = p->NextC( coupling::control ) ) != nullptr ) ) {
auto const *vehicle { p->MoverParameters }; auto const *vehicle { p->MoverParameters };
IsAnyConverterOverloadRelayOpen |= vehicle->ConvOvldFlag;
IsAnyMotorOverloadRelayOpen |= vehicle->FuseFlag;
IsAnyGroundRelayOpen |= !vehicle->GroundRelay;
IsAnyCompressorEnabled |= vehicle->CompressorAllow;
if( vehicle->Power > 0.01 ) { if( vehicle->Power > 0.01 ) {
IsLineBreakerClosed = ( IsLineBreakerClosed && vehicle->Mains ); IsAnyLineBreakerOpen |= !vehicle->Mains;
} }
} }
@@ -4795,7 +4804,7 @@ TController::UpdateSituation(double dt) {
} }
// uśrednione napięcie sieci: przy spadku poniżej wartości minimalnej opóźnić rozruch o losowy czas // uśrednione napięcie sieci: przy spadku poniżej wartości minimalnej opóźnić rozruch o losowy czas
fVoltage = 0.5 * (fVoltage + std::max( mvControlling->GetAnyTrainsetVoltage(), mvControlling->PantographVoltage ) ); fVoltage = 0.5 * (fVoltage + std::max( mvControlling->GetTrainsetHighVoltage(), mvControlling->PantographVoltage ) );
if( fVoltage < mvControlling->EnginePowerSource.CollectorParameters.MinV ) { if( fVoltage < mvControlling->EnginePowerSource.CollectorParameters.MinV ) {
// gdy rozłączenie WS z powodu niskiego napięcia // gdy rozłączenie WS z powodu niskiego napięcia
if( fActionTime >= PrepareTime ) { if( fActionTime >= PrepareTime ) {
@@ -4840,11 +4849,11 @@ TController::UpdateSituation(double dt) {
if( ( fOverhead2 > 0.0 ) || iOverheadDown ) { if( ( fOverhead2 > 0.0 ) || iOverheadDown ) {
// jazda z opuszczonymi pantografami // jazda z opuszczonymi pantografami
if( mvControlling->Pantographs[ end::front ].is_active ) { if( mvPantographUnit->Pantographs[ end::front ].is_active ) {
mvControlling->OperatePantographValve( end::front, operation_t::disable ); mvOccupied->OperatePantographValve( end::front, operation_t::disable );
} }
if( mvControlling->Pantographs[ end::rear ].is_active ) { if( mvPantographUnit->Pantographs[ end::rear ].is_active ) {
mvControlling->OperatePantographValve( end::rear, operation_t::disable ); mvOccupied->OperatePantographValve( end::rear, operation_t::disable );
} }
} }
else { else {
@@ -4854,37 +4863,37 @@ TController::UpdateSituation(double dt) {
// jazda na tylnym // jazda na tylnym
if( ( iDirection >= 0 ) && ( useregularpantographlayout ) ) { if( ( iDirection >= 0 ) && ( useregularpantographlayout ) ) {
// jak jedzie w kierunku sprzęgu 0 // jak jedzie w kierunku sprzęgu 0
if( ( mvControlling->PantRearVolt == 0.0 ) if( ( mvPantographUnit->PantRearVolt == 0.0 )
// filter out cases with single _other_ working pantograph so we don't try to raise something we can't // filter out cases with single _other_ working pantograph so we don't try to raise something we can't
&& ( ( mvControlling->PantographVoltage == 0.0 ) && ( ( mvPantographUnit->PantographVoltage == 0.0 )
|| ( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) ) ) { || ( mvPantographUnit->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) ) ) {
mvControlling->OperatePantographValve( end::rear, operation_t::enable ); mvOccupied->OperatePantographValve( end::rear, operation_t::enable );
} }
} }
else { else {
// jak jedzie w kierunku sprzęgu 0 // jak jedzie w kierunku sprzęgu 0
if( ( mvControlling->PantFrontVolt == 0.0 ) if( ( mvPantographUnit->PantFrontVolt == 0.0 )
// filter out cases with single _other_ working pantograph so we don't try to raise something we can't // filter out cases with single _other_ working pantograph so we don't try to raise something we can't
&& ( ( mvControlling->PantographVoltage == 0.0 ) && ( ( mvPantographUnit->PantographVoltage == 0.0 )
|| ( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) ) ) { || ( mvPantographUnit->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) ) ) {
mvControlling->OperatePantographValve( end::front, operation_t::enable ); mvOccupied->OperatePantographValve( end::front, operation_t::enable );
} }
} }
if( mvOccupied->Vel > 5 ) { if( mvOccupied->Vel > 5 ) {
// opuszczenie przedniego po rozpędzeniu się o ile jest więcej niż jeden // opuszczenie przedniego po rozpędzeniu się o ile jest więcej niż jeden
if( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) { if( mvPantographUnit->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) {
if( ( iDirection >= 0 ) && ( useregularpantographlayout ) ) // jak jedzie w kierunku sprzęgu 0 if( ( iDirection >= 0 ) && ( useregularpantographlayout ) ) // jak jedzie w kierunku sprzęgu 0
{ // poczekać na podniesienie tylnego { // poczekać na podniesienie tylnego
if( ( mvControlling->PantFrontVolt != 0.0 ) if( ( mvPantographUnit->PantFrontVolt != 0.0 )
&& ( mvControlling->PantRearVolt != 0.0 ) ) { // czy jest napięcie zasilające na tylnym? && ( mvPantographUnit->PantRearVolt != 0.0 ) ) { // czy jest napięcie zasilające na tylnym?
mvControlling->OperatePantographValve( end::front, operation_t::disable ); // opuszcza od sprzęgu 0 mvOccupied->OperatePantographValve( end::front, operation_t::disable ); // opuszcza od sprzęgu 0
} }
} }
else { // poczekać na podniesienie przedniego else { // poczekać na podniesienie przedniego
if( ( mvControlling->PantRearVolt != 0.0 ) if( ( mvPantographUnit->PantRearVolt != 0.0 )
&& ( mvControlling->PantFrontVolt != 0.0 ) ) { // czy jest napięcie zasilające na przednim? && ( mvPantographUnit->PantFrontVolt != 0.0 ) ) { // czy jest napięcie zasilające na przednim?
mvControlling->OperatePantographValve( end::rear, operation_t::disable ); // opuszcza od sprzęgu 1 mvOccupied->OperatePantographValve( end::rear, operation_t::disable ); // opuszcza od sprzęgu 1
} }
} }
} }
@@ -4895,12 +4904,12 @@ TController::UpdateSituation(double dt) {
// use suggested pantograph setup // use suggested pantograph setup
if( mvOccupied->Vel > 5 ) { if( mvOccupied->Vel > 5 ) {
auto const pantographsetup{ mvOccupied->AIHintPantstate }; auto const pantographsetup{ mvOccupied->AIHintPantstate };
mvControlling->OperatePantographValve( mvOccupied->OperatePantographValve(
end::front, end::front,
( pantographsetup & ( 1 << 0 ) ? ( pantographsetup & ( 1 << 0 ) ?
operation_t::enable : operation_t::enable :
operation_t::disable ) ); operation_t::disable ) );
mvControlling->OperatePantographValve( mvOccupied->OperatePantographValve(
end::rear, end::rear,
( pantographsetup & ( 1 << 1 ) ? ( pantographsetup & ( 1 << 1 ) ?
operation_t::enable : operation_t::enable :
@@ -4946,16 +4955,16 @@ TController::UpdateSituation(double dt) {
// NOTE: abs(stoptime) covers either at least 15 sec remaining for a scheduled stop, or 15+ secs spent at a basic stop // NOTE: abs(stoptime) covers either at least 15 sec remaining for a scheduled stop, or 15+ secs spent at a basic stop
&& ( std::abs( fStopTime ) > 15.0 ) ) { && ( std::abs( fStopTime ) > 15.0 ) ) {
// spending a longer at a stop, raise also front pantograph // spending a longer at a stop, raise also front pantograph
if( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) { if( mvPantographUnit->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) {
if( ( iDirection >= 0 ) && ( useregularpantographlayout ) ) { if( ( iDirection >= 0 ) && ( useregularpantographlayout ) ) {
// jak jedzie w kierunku sprzęgu 0 // jak jedzie w kierunku sprzęgu 0
if( mvControlling->PantFrontVolt == 0.0 ) { if( mvPantographUnit->PantFrontVolt == 0.0 ) {
mvControlling->OperatePantographValve( end::front, operation_t::enable ); mvOccupied->OperatePantographValve( end::front, operation_t::enable );
} }
} }
else { else {
if( mvControlling->PantRearVolt == 0.0 ) { if( mvPantographUnit->PantRearVolt == 0.0 ) {
mvControlling->OperatePantographValve( end::rear, operation_t::enable ); mvOccupied->OperatePantographValve( end::rear, operation_t::enable );
} }
} }
} }
@@ -6237,29 +6246,31 @@ TController::UpdateSituation(double dt) {
return; // ...and don't touch any other controls return; // ...and don't touch any other controls
} }
if( ( true == mvControlling->ConvOvldFlag ) // wywalił bezpiecznik nadmiarowy przetwornicy if( ( IsAnyConverterOverloadRelayOpen ) // wywalił bezpiecznik nadmiarowy przetwornicy
|| ( false == IsLineBreakerClosed ) ) { // WS może wywalić z powodu błędu w drutach || ( IsAnyLineBreakerOpen ) ) { // WS może wywalić z powodu błędu w drutach
// próba ponownego załączenia // próba ponownego załączenia
PrepareEngine(); PrepareEngine();
} }
// włączanie bezpiecznika // włączanie bezpiecznika
if ((mvControlling->EngineType == TEngineType::ElectricSeriesMotor) || if( ( mvControlling->EngineType == TEngineType::ElectricSeriesMotor )
(mvControlling->TrainType & dt_EZT) || || ( mvControlling->EngineType == TEngineType::DieselElectric )
(mvControlling->EngineType == TEngineType::DieselElectric)) || ( mvControlling->TrainType == dt_EZT ) ) {
if (mvControlling->FuseFlag || Need_TryAgain || (false == mvControlling->GroundRelay)) if( Need_TryAgain ) {
{ // true, jeśli druga pozycja w elektryku nie załapała
Need_TryAgain = false; // true, jeśli druga pozycja w elektryku nie załapała ZeroSpeed();
mvControlling->DecScndCtrl(2); // nastawnik bocznikowania na 0 Need_TryAgain = false;
mvControlling->DecMainCtrl(2); // nastawnik jazdy na 0
if (mvControlling->FuseOn()) {
++iDriverFailCount;
if (iDriverFailCount > maxdriverfails)
Psyche = Easyman;
if (iDriverFailCount > maxdriverfails * 2)
SetDriverPsyche();
}
mvControlling->MainSwitch(true); // Ra: dodałem, bo EN57 stawały po wywaleniu
} }
if( IsAnyMotorOverloadRelayOpen || IsAnyGroundRelayOpen ) {
ZeroSpeed();
mvOccupied->FuseOn();
mvControlling->MainSwitch( true ); // Ra: dodałem, bo EN57 stawały po wywaleniu
++iDriverFailCount;
if( iDriverFailCount > maxdriverfails )
Psyche = Easyman;
if( iDriverFailCount > maxdriverfails * 2 )
SetDriverPsyche();
}
}
// NOTE: as a stop-gap measure the routine is limited to trains only while car calculations seem off // NOTE: as a stop-gap measure the routine is limited to trains only while car calculations seem off
if( mvControlling->CategoryFlag == 1 ) { if( mvControlling->CategoryFlag == 1 ) {
if( vel < VelDesired ) { if( vel < VelDesired ) {
@@ -6542,7 +6553,7 @@ TController::UpdateSituation(double dt) {
else else
{ // tutaj, gdy pojazd jest wyłączony { // tutaj, gdy pojazd jest wyłączony
if (!AIControllFlag) // jeśli sterowanie jest w gestii użytkownika if (!AIControllFlag) // jeśli sterowanie jest w gestii użytkownika
if (mvOccupied->Battery) // czy użytkownik załączył baterię? if (mvOccupied->Power24vIsAvailable) // czy użytkownik załączył baterię?
if (mvOccupied->DirActive) // czy ustawił kierunek if (mvOccupied->DirActive) // czy ustawił kierunek
{ // jeśli tak, to uruchomienie skanowania { // jeśli tak, to uruchomienie skanowania
CheckVehicles(); // sprawdzić skład CheckVehicles(); // sprawdzić skład
@@ -7385,7 +7396,14 @@ void TController::ControllingSet()
// dzięki temu będzie wirtualna kabina w silnikowym, działająca w rozrządczym // dzięki temu będzie wirtualna kabina w silnikowym, działająca w rozrządczym
// w plikach FIZ zostały zgubione ujemne maski sprzęgów, stąd problemy z EZT // w plikach FIZ zostały zgubione ujemne maski sprzęgów, stąd problemy z EZT
mvOccupied = pVehicle->MoverParameters; // domyślny skrót do obiektu parametrów mvOccupied = pVehicle->MoverParameters; // domyślny skrót do obiektu parametrów
mvControlling = pVehicle->ControlledFind()->MoverParameters; // poszukiwanie członu sterowanego mvControlling = pVehicle->FindPowered()->MoverParameters; // poszukiwanie członu sterowanego
{
auto *lookup { pVehicle->FindPantographCarrier() };
mvPantographUnit = (
lookup != nullptr ?
lookup->MoverParameters :
mvControlling );
}
}; };
std::string TController::TableText( std::size_t const Index ) const std::string TController::TableText( std::size_t const Index ) const

127
Driver.h
View File

@@ -193,19 +193,22 @@ public:
// ai operations logic // ai operations logic
// methods // methods
public: public:
void UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę void UpdateSituation( double dt ); // uruchamiac przynajmniej raz na sekundę
void MoveTo(TDynamicObject *to); void MoveTo( TDynamicObject *to );
void TakeControl(bool const Aidriver, bool const Forcevehiclecheck = false); void TakeControl( bool const Aidriver, bool const Forcevehiclecheck = false );
inline inline
bool primary( bool const Primary ) { bool primary( bool const Primary ) {
SetFlag( iDrivigFlags, ( Primary ? movePrimary : -movePrimary ) ); SetFlag( iDrivigFlags, ( Primary ? movePrimary : -movePrimary ) );
return primary(); } return primary();
}
inline inline
bool primary() const { bool primary() const {
return ( ( iDrivigFlags & movePrimary ) != 0 ); }; return ( ( iDrivigFlags & movePrimary ) != 0 );
};
inline inline
TMoverParameters const *Controlling() const { TMoverParameters const *Controlling() const {
return mvControlling; } return mvControlling;
}
inline inline
TMoverParameters const *Occupied() const { TMoverParameters const *Occupied() const {
return mvOccupied; return mvOccupied;
@@ -213,14 +216,17 @@ public:
void DirectionInitial(); void DirectionInitial();
void DirectionChange(); void DirectionChange();
inline inline
int Direction() const { int Direction() const {
return iDirection; } return iDirection;
}
inline inline
TAction & action() { TAction & action() {
return eAction; } return eAction;
}
inline inline
TAction const & action() const { TAction const & action() const {
return eAction; } return eAction;
}
private: private:
void Activation(); // umieszczenie obsady w odpowiednim członie void Activation(); // umieszczenie obsady w odpowiednim członie
void ControllingSet(); // znajduje człon do sterowania void ControllingSet(); // znajduje człon do sterowania
@@ -229,54 +235,56 @@ private:
bool DecBrake(); bool DecBrake();
bool ZeroLocalBrake(); bool ZeroLocalBrake();
bool IncSpeed(); bool IncSpeed();
bool DecSpeed(bool force = false); bool DecSpeed( bool force = false );
void ZeroSpeed( bool const Enforce = false ); void ZeroSpeed( bool const Enforce = false );
bool IncBrakeEIM(); bool IncBrakeEIM();
bool DecBrakeEIM(); bool DecBrakeEIM();
bool IncSpeedEIM(); bool IncSpeedEIM();
bool DecSpeedEIM(); bool DecSpeedEIM();
void BrakeLevelSet(double b); void BrakeLevelSet( double b );
bool BrakeLevelAdd(double b); bool BrakeLevelAdd( double b );
void SpeedSet(); void SpeedSet();
void SpeedCntrl(double DesiredSpeed); void SpeedCntrl( double DesiredSpeed );
void SetTimeControllers(); /*setting state of time controllers depending of desired action*/ void SetTimeControllers(); /*setting state of time controllers depending of desired action*/
void CheckTimeControllers(); /*checking state of time controllers to reset them to stable position*/ void CheckTimeControllers(); /*checking state of time controllers to reset them to stable position*/
double ESMVelocity(bool Main); double ESMVelocity( bool Main );
bool UpdateHeating(); bool UpdateHeating();
// uaktualnia informacje o prędkości // uaktualnia informacje o prędkości
void SetVelocity(double NewVel, double NewVelNext, TStopReason r = stopNone); void SetVelocity( double NewVel, double NewVelNext, TStopReason r = stopNone );
int CheckDirection(); int CheckDirection();
void WaitingSet(double Seconds); void WaitingSet( double Seconds );
void DirectionForward(bool forward); void DirectionForward( bool forward );
void ZeroDirection(); void ZeroDirection();
int OrderDirectionChange(int newdir, TMoverParameters *Vehicle); int OrderDirectionChange( int newdir, TMoverParameters *Vehicle );
void sync_consist_reversers(); void sync_consist_reversers();
void Lights(int head, int rear); void Lights( int head, int rear );
std::string StopReasonText() const; std::string StopReasonText() const;
double BrakeAccFactor() const; double BrakeAccFactor() const;
// modifies brake distance for low target speeds, to ease braking rate in such situations // modifies brake distance for low target speeds, to ease braking rate in such situations
float float
braking_distance_multiplier( float const Targetvelocity ) const; braking_distance_multiplier( float const Targetvelocity ) const;
inline inline
int DrivigFlags() const { int DrivigFlags() const {
return iDrivigFlags; }; return iDrivigFlags;
};
// members // members
public: public:
bool AIControllFlag = false; // rzeczywisty/wirtualny maszynista bool AIControllFlag = false; // rzeczywisty/wirtualny maszynista
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 UniversalBrakeButtons = 0.0; // flag of which universal buttons need to be pressed int UniversalBrakeButtons = 0.0; // flag of which universal buttons need to be pressed
int DizelPercentage = 0; // oczekiwane procenty jazdy/hamowania szynobusem int DizelPercentage = 0; // oczekiwane procenty jazdy/hamowania szynobusem
int DizelPercentage_Speed = 0; // oczekiwane procenty jazdy/hamowania szynobusem w związku z osiąganiem VelDesired 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
TDynamicObject *pVehicle = nullptr; // pojazd w którym siedzi sterujący TDynamicObject *pVehicle = nullptr; // pojazd w którym siedzi sterujący
TMoverParameters *mvControlling = nullptr; // jakim pojazdem steruje (może silnikowym w EZT) TMoverParameters *mvControlling = nullptr; // jakim pojazdem steruje (może silnikowym w EZT)
TMoverParameters *mvOccupied = nullptr; // jakim pojazdem hamuje TMoverParameters *mvOccupied = nullptr; // jakim pojazdem hamuje
TMoverParameters *mvPantographUnit = nullptr; //pantograph equipped vehicle in the occupied/controlled set
std::string VehicleName; std::string VehicleName;
std::array<int, 2> m_lighthints { -1 }; // suggested light patterns std::array<int, 2> m_lighthints = { -1, -1 }; // suggested light patterns
double AccPreferred = 0.0; // preferowane przyspieszenie (wg psychiki kierującego, zmniejszana przy wykryciu kolizji) double AccPreferred = 0.0; // preferowane przyspieszenie (wg psychiki kierującego, zmniejszana przy wykryciu kolizji)
double AccDesired = AccPreferred; // przyspieszenie, jakie ma utrzymywać (<0:nie przyspieszaj,<-0.1:hamuj) double AccDesired = AccPreferred; // przyspieszenie, jakie ma utrzymywać (<0:nie przyspieszaj,<-0.1:hamuj)
double VelDesired = 0.0; // predkość, z jaką ma jechać, wynikająca z analizy tableki; <=VelSignal double VelDesired = 0.0; // predkość, z jaką ma jechać, wynikająca z analizy tableki; <=VelSignal
@@ -311,7 +319,7 @@ private:
double fWarningDuration = 0.0; // ile czasu jeszcze trąbić double fWarningDuration = 0.0; // ile czasu jeszcze trąbić
double WaitingTime = 0.0; // zliczany czas oczekiwania do samoistnego ruszenia double WaitingTime = 0.0; // zliczany czas oczekiwania do samoistnego ruszenia
double WaitingExpireTime = 31.0; // tyle ma czekać, zanim się ruszy // maksymlany czas oczekiwania do samoistnego ruszenia double WaitingExpireTime = 31.0; // tyle ma czekać, zanim się ruszy // maksymlany czas oczekiwania do samoistnego ruszenia
double IdleTime {}; // keeps track of time spent at a stop double IdleTime{}; // keeps track of time spent at a stop
double fStopTime = 0.0; // czas postoju przed dalszą jazdą (np. na przystanku) double fStopTime = 0.0; // czas postoju przed dalszą jazdą (np. na przystanku)
float ExchangeTime{ 0.0 }; // time needed to finish current load exchange float ExchangeTime{ 0.0 }; // time needed to finish current load exchange
double fShuntVelocity = 40.0; // maksymalna prędkość manewrowania, zależy m.in. od składu // domyślna prędkość manewrowa double fShuntVelocity = 40.0; // maksymalna prędkość manewrowania, zależy m.in. od składu // domyślna prędkość manewrowa
@@ -323,29 +331,29 @@ private:
double fDriverDist = 0.0; // dopuszczalna odległość podjechania do przeszkody double fDriverDist = 0.0; // dopuszczalna odległość podjechania do przeszkody
double fVelMax = -1.0; // maksymalna prędkość składu (sprawdzany każdy pojazd) double fVelMax = -1.0; // maksymalna prędkość składu (sprawdzany każdy pojazd)
double fBrakeDist = 0.0; // przybliżona droga hamowania double fBrakeDist = 0.0; // przybliżona droga hamowania
double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h) double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h)
double fNominalAccThreshold = 0.0; // nominalny próg opóźnienia dla zadziałania hamulca double fNominalAccThreshold = 0.0; // nominalny próg opóźnienia dla zadziałania hamulca
double fAccThreshold = 0.0; // aktualny próg opóźnienia dla zadziałania hamulca double fAccThreshold = 0.0; // aktualny próg opóźnienia dla zadziałania hamulca
double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca
// dla fBrake_aX: // dla fBrake_aX:
// indeks [0] - wartości odpowiednie dla aktualnej prędkości // indeks [0] - wartości odpowiednie dla aktualnej prędkości
// a potem jest 20 wartości dla różnych prędkości zmieniających się co 5 % Vmax pojazdu obsadzonego // a potem jest 20 wartości dla różnych prędkości zmieniających się co 5 % Vmax pojazdu obsadzonego
double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // opóźnienia hamowania przy ustawieniu zaworu maszynisty w pozycji 1.0 double fBrake_a0[ BrakeAccTableSize + 1 ] = { 0.0 }; // opóźnienia hamowania przy ustawieniu zaworu maszynisty w pozycji 1.0
double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // przyrost opóźnienia hamowania po przestawieniu zaworu maszynisty o 0,25 pozycji double fBrake_a1[ BrakeAccTableSize + 1 ] = { 0.0 }; // przyrost opóźnienia hamowania po przestawieniu zaworu maszynisty o 0,25 pozycji
double BrakingInitialLevel{ 1.0 }; double BrakingInitialLevel{ 1.0 };
double BrakingLevelIncrease{ 0.25 }; double BrakingLevelIncrease{ 0.25 };
double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI
double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
double BrakeChargingCooldown {}; // prevents the ai from trying to charge the train brake too frequently double BrakeChargingCooldown{}; // prevents the ai from trying to charge the train brake too frequently
double LastReactionTime = 0.0; double LastReactionTime = 0.0;
double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi
double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations
TAction eAction { TAction::actUnknown }; // aktualny stan TAction eAction{ TAction::actUnknown }; // aktualny stan
// orders // orders
// methods // methods
public: public:
void PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation, TStopReason reason = stopComm); void PutCommand( std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation, TStopReason reason = stopComm );
bool PutCommand( std::string NewCommand, double NewValue1, double NewValue2, glm::dvec3 const *NewLocation, TStopReason reason = stopComm ); bool PutCommand( std::string NewCommand, double NewValue1, double NewValue2, glm::dvec3 const *NewLocation, TStopReason reason = stopComm );
// defines assignment data // defines assignment data
inline auto assignment() -> std::string & { return m_assignment; } inline auto assignment() -> std::string & { return m_assignment; }
@@ -355,15 +363,15 @@ private:
void RecognizeCommand(); // odczytuje komende przekazana lokomotywie void RecognizeCommand(); // odczytuje komende przekazana lokomotywie
void JumpToNextOrder(); void JumpToNextOrder();
void JumpToFirstOrder(); void JumpToFirstOrder();
void OrderPush(TOrders NewOrder); void OrderPush( TOrders NewOrder );
void OrderNext(TOrders NewOrder); void OrderNext( TOrders NewOrder );
inline TOrders OrderCurrentGet() const; inline TOrders OrderCurrentGet() const;
inline TOrders OrderNextGet() const; inline TOrders OrderNextGet() const;
void OrderCheck(); void OrderCheck();
void OrdersInit(double fVel); void OrdersInit( double fVel );
void OrdersClear(); void OrdersClear();
void OrdersDump(); void OrdersDump();
std::string Order2Str(TOrders Order) const; std::string Order2Str( TOrders Order ) const;
// members // members
std::string m_assignment; std::string m_assignment;
Math3D::vector3 vCommandLocation; // polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego odnosi sie komenda // NOTE: not used Math3D::vector3 vCommandLocation; // polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego odnosi sie komenda // NOTE: not used
@@ -374,9 +382,10 @@ private:
// scantable // scantable
// methods // methods
public: public:
int CrossRoute(TTrack *tr); int CrossRoute( TTrack *tr );
inline void MoveDistanceAdd( double distance ) { inline void MoveDistanceAdd( double distance ) {
dMoveLen += distance * iDirection; } //jak jedzie do tyłu to trzeba uwzględniać, że distance jest ujemna dMoveLen += distance * iDirection;
} //jak jedzie do tyłu to trzeba uwzględniać, że distance jest ujemna
private: private:
// Ra: metody obsługujące skanowanie toru // Ra: metody obsługujące skanowanie toru
std::vector<basic_event *> CheckTrackEvent( TTrack *Track, double const fDirection ) const; std::vector<basic_event *> CheckTrackEvent( TTrack *Track, double const fDirection ) const;
@@ -404,7 +413,7 @@ private:
TTrack *BackwardTraceRoute( double &fDistance, double &fDirection, TTrack *Track, basic_event *&Event ); TTrack *BackwardTraceRoute( double &fDistance, double &fDirection, TTrack *Track, basic_event *&Event );
void SetProximityVelocity( double dist, double vel, glm::dvec3 const *pos ); void SetProximityVelocity( double dist, double vel, glm::dvec3 const *pos );
TCommandType BackwardScan(); TCommandType BackwardScan();
std::string TableText(std::size_t const Index) const; std::string TableText( std::size_t const Index ) const;
/* /*
void RouteSwitch(int d); void RouteSwitch(int d);
*/ */
@@ -415,7 +424,7 @@ private:
double fLastVel = 0.0; // prędkość na poprzednio sprawdzonym torze double fLastVel = 0.0; // prędkość na poprzednio sprawdzonym torze
TTrack *tLast = nullptr; // ostatni analizowany tor TTrack *tLast = nullptr; // ostatni analizowany tor
basic_event *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu basic_event *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu
std::size_t SemNextIndex{ std::size_t(-1) }; std::size_t SemNextIndex{ std::size_t( -1 ) };
std::size_t SemNextStopIndex{ std::size_t( -1 ) }; std::size_t SemNextStopIndex{ std::size_t( -1 ) };
double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki
basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2] basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2]
@@ -442,7 +451,7 @@ private:
double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku
int iRadioChannel = 1; // numer aktualnego kanału radiowego int iRadioChannel = 1; // numer aktualnego kanału radiowego
int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia) int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia)
sound_source tsGuardSignal { sound_placement::internal }; sound_source tsGuardSignal{ sound_placement::internal };
// consist // consist
// methods // methods
@@ -451,7 +460,7 @@ public:
private: private:
bool PrepareEngine(); bool PrepareEngine();
bool ReleaseEngine(); bool ReleaseEngine();
void Doors(bool const Open, int const Side = 0); void Doors( bool const Open, int const Side = 0 );
// returns true if any vehicle in the consist has an open door // returns true if any vehicle in the consist has an open door
bool doors_open() const; bool doors_open() const;
void AutoRewident(); // ustawia hamulce w składzie void AutoRewident(); // ustawia hamulce w składzie
@@ -465,12 +474,16 @@ private:
bool iEngineActive{ false }; // ABu: Czy silnik byl juz zalaczony bool iEngineActive{ false }; // ABu: Czy silnik byl juz zalaczony
bool IsCargoTrain{ false }; bool IsCargoTrain{ false };
bool IsHeavyCargoTrain{ false }; bool IsHeavyCargoTrain{ false };
bool IsLineBreakerClosed{ false }; // state of line breaker in all powered vehicles under control
double fReady = 0.0; // poziom odhamowania wagonów double fReady = 0.0; // poziom odhamowania wagonów
bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow
double ConsistShade{ 1.0 }; // averaged amount of sunlight received by the consist double ConsistShade{ 1.0 }; // averaged amount of sunlight received by the consist
TDynamicObject *pVehicles[ 2 ]; // skrajne pojazdy w składzie (niekoniecznie bezpośrednio sterowane) TDynamicObject *pVehicles[ 2 ]; // skrajne pojazdy w składzie (niekoniecznie bezpośrednio sterowane)
bool IsAnyDoorOpen[ 2 ]; // state of door in the consist bool IsAnyDoorOpen[ 2 ]; // state of door in the consist
bool IsAnyLineBreakerOpen{ false }; // state of line breaker in all powered vehicles under control
bool IsAnyConverterOverloadRelayOpen{ false }; // state of converter overload relays in all vehicles under control
bool IsAnyMotorOverloadRelayOpen{ false }; // state of motor overload relays in all vehicles under control
bool IsAnyGroundRelayOpen{ false };
bool IsAnyCompressorEnabled{ false };
// logs // logs
// methods // methods

View File

@@ -956,7 +956,7 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
btnOn = true; btnOn = true;
} }
// else btCPass2.TurnOff(); // else btCPass2.TurnOff();
if (MoverParameters->Battery || MoverParameters->ConverterFlag) if (MoverParameters->Power24vIsAvailable || MoverParameters->Power110vIsAvailable)
{ // sygnaly konca pociagu { // sygnaly konca pociagu
if (btEndSignals1.Active()) if (btEndSignals1.Active())
{ {
@@ -1056,7 +1056,7 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
} // vehicle within 400m } // vehicle within 400m
if( MoverParameters->Battery || MoverParameters->ConverterFlag ) if( MoverParameters->Power24vIsAvailable || MoverParameters->Power110vIsAvailable )
{ // sygnały czoła pociagu //Ra: wyświetlamy bez { // sygnały czoła pociagu //Ra: wyświetlamy bez
// ograniczeń odległości, by były widoczne z // ograniczeń odległości, by były widoczne z
// daleka // daleka
@@ -2782,8 +2782,10 @@ void TDynamicObject::update_destinations() {
if( DestinationSign.sign == nullptr ) { return; } if( DestinationSign.sign == nullptr ) { return; }
auto const lowvoltagepower { ( MoverParameters->Power24vIsAvailable || MoverParameters->Power110vIsAvailable ) };
DestinationSign.sign->fLight = ( DestinationSign.sign->fLight = (
( ( DestinationSign.has_light ) && ( MoverParameters->Battery ) ) ? ( ( DestinationSign.has_light ) && ( lowvoltagepower ) ) ?
2.0 : 2.0 :
-1.0 ); -1.0 );
@@ -2793,7 +2795,7 @@ void TDynamicObject::update_destinations() {
m_materialdata.replacable_skins[ 4 ] = ( m_materialdata.replacable_skins[ 4 ] = (
( ( DestinationSign.destination != null_handle ) ( ( DestinationSign.destination != null_handle )
&& ( ( false == DestinationSign.has_light ) // physical destination signs remain up until manually changed && ( ( false == DestinationSign.has_light ) // physical destination signs remain up until manually changed
|| ( ( true == MoverParameters->Battery ) // lcd signs are off without power || ( ( lowvoltagepower ) // lcd signs are off without power
&& ( ctOwner != nullptr ) ) ) ) ? // lcd signs are off for carriages without engine, potentially left on a siding && ( ctOwner != nullptr ) ) ) ) ? // lcd signs are off for carriages without engine, potentially left on a siding
DestinationSign.destination : DestinationSign.destination :
DestinationSign.destination_off ); DestinationSign.destination_off );
@@ -2905,7 +2907,7 @@ bool TDynamicObject::Update(double dt, double dt1)
|| MoverParameters->Pantographs[end::rear].is_active ) { || MoverParameters->Pantographs[end::rear].is_active ) {
if( ( MoverParameters->Mains ) if( ( MoverParameters->Mains )
&& ( MoverParameters->GetAnyTrainsetVoltage() < 0.1f ) ) { && ( MoverParameters->GetTrainsetHighVoltage() < 0.1f ) ) {
// Ra 15-01: logować tylko, jeśli WS załączony // Ra 15-01: logować tylko, jeśli WS załączony
// yB 16-03: i nie jest to asynchron zasilany z daleka // yB 16-03: i nie jest to asynchron zasilany z daleka
// Ra 15-01: bezwzględne współrzędne pantografu nie są dostępne, // Ra 15-01: bezwzględne współrzędne pantografu nie są dostępne,
@@ -3275,8 +3277,7 @@ bool TDynamicObject::Update(double dt, double dt1)
// fragment "z EXE Kursa" // fragment "z EXE Kursa"
if( MoverParameters->Mains ) { // nie wchodzić w funkcję bez potrzeby if( MoverParameters->Mains ) { // nie wchodzić w funkcję bez potrzeby
if( ( false == MoverParameters->Battery ) if( ( false == ( MoverParameters->Power24vIsAvailable || MoverParameters->Power110vIsAvailable ) )
&& ( false == MoverParameters->ConverterFlag ) // added alternative power source. TODO: more generic power check
/* /*
// NOTE: disabled on account of multi-unit setups, where the unmanned unit wouldn't be affected // NOTE: disabled on account of multi-unit setups, where the unmanned unit wouldn't be affected
&& ( Controller == Humandriver ) && ( Controller == Humandriver )
@@ -3607,8 +3608,7 @@ bool TDynamicObject::Update(double dt, double dt1)
else { else {
pantspeedfactor = 0.0; pantspeedfactor = 0.0;
} }
if( ( false == MoverParameters->Battery ) if( false == ( MoverParameters->Power24vIsAvailable || MoverParameters->Power110vIsAvailable ) ) {
&& ( false == MoverParameters->ConverterFlag ) ) {
pantspeedfactor = 0.0; pantspeedfactor = 0.0;
} }
pantspeedfactor = std::max( 0.0, pantspeedfactor ); pantspeedfactor = std::max( 0.0, pantspeedfactor );
@@ -3952,7 +3952,7 @@ void TDynamicObject::RenderSounds() {
// NBMX dzwiek przetwornicy // NBMX dzwiek przetwornicy
if( MoverParameters->ConverterFlag ) { if( MoverParameters->ConverterFlag ) {
if( MoverParameters->EngineType == TEngineType::ElectricSeriesMotor ) { if( MoverParameters->EngineType == TEngineType::ElectricSeriesMotor ) {
auto const voltage { std::max( MoverParameters->GetAnyTrainsetVoltage(), MoverParameters->PantographVoltage ) }; auto const voltage { std::max( MoverParameters->GetTrainsetHighVoltage(), MoverParameters->PantographVoltage ) };
if( voltage > 0.0 ) { if( voltage > 0.0 ) {
// NOTE: we do sound modulation here to avoid sudden jump on voltage loss // NOTE: we do sound modulation here to avoid sudden jump on voltage loss
frequency = ( voltage / ( MoverParameters->NominalVoltage * MoverParameters->RList[ MoverParameters->RlistSize ].Mn ) ); frequency = ( voltage / ( MoverParameters->NominalVoltage * MoverParameters->RList[ MoverParameters->RlistSize ].Mn ) );
@@ -4171,9 +4171,11 @@ void TDynamicObject::RenderSounds() {
} }
// NBMX sygnal odjazdu // NBMX sygnal odjazdu
if( MoverParameters->Doors.has_warning ) { if( MoverParameters->Doors.has_warning ) {
auto const lowvoltagepower { MoverParameters->Power24vIsAvailable || MoverParameters->Power110vIsAvailable };
for( auto &departuresignalsound : m_departuresignalsounds ) { for( auto &departuresignalsound : m_departuresignalsounds ) {
// TBD, TODO: per-location door state triggers? // TBD, TODO: per-location door state triggers?
if( ( MoverParameters->DepartureSignal ) if( ( MoverParameters->DepartureSignal )
&& ( lowvoltagepower )
/* /*
|| ( ( MoverParameters->DoorCloseCtrl = control::autonomous ) || ( ( MoverParameters->DoorCloseCtrl = control::autonomous )
&& ( ( ( false == MoverParameters->DoorLeftOpened ) && ( dDoorMoveL > 0.0 ) ) && ( ( ( false == MoverParameters->DoorLeftOpened ) && ( dDoorMoveL > 0.0 ) )
@@ -6209,7 +6211,9 @@ void TDynamicObject::Damage(char flag)
if (flag & 4) //blokada przetwornicy if (flag & 4) //blokada przetwornicy
{ {
MoverParameters->ConvOvldFlag = true; if( MoverParameters->ConverterStart != start_t::disabled ) {
MoverParameters->ConvOvldFlag = true;
}
} }
else else
{ {
@@ -6522,7 +6526,7 @@ TDynamicObject::find_vehicle( int const Direction, double const Distance ) const
return { foundobject, foundcoupler, distance, true }; return { foundobject, foundcoupler, distance, true };
} }
TDynamicObject * TDynamicObject::ControlledFind() TDynamicObject * TDynamicObject::FindPowered()
{ // taka proteza: { // taka proteza:
// chcę podłączyć kabinę EN57 bezpośrednio z silnikowym, aby nie robić tego przez ukrotnienie // chcę podłączyć kabinę EN57 bezpośrednio z silnikowym, aby nie robić tego przez ukrotnienie
// drugi silnikowy i tak musi być ukrotniony, podobnie jak kolejna jednostka // drugi silnikowy i tak musi być ukrotniony, podobnie jak kolejna jednostka
@@ -6533,33 +6537,42 @@ TDynamicObject * TDynamicObject::ControlledFind()
// problematyczna może być kwestia wybranej kabiny (w silnikowym...) // problematyczna może być kwestia wybranej kabiny (w silnikowym...)
// jeśli silnikowy będzie zapięty odwrotnie (tzn. -1), to i tak powinno jeździć dobrze // jeśli silnikowy będzie zapięty odwrotnie (tzn. -1), to i tak powinno jeździć dobrze
// również hamowanie wykonuje się zaworem w członie, a nie w silnikowym... // również hamowanie wykonuje się zaworem w członie, a nie w silnikowym...
if( MoverParameters->Power > 1.0 ) { return this; } auto const coupling { (
( MoverParameters->TrainType == dt_EZT ) || ( MoverParameters->TrainType == dt_DMU ) ) ?
coupling::permanent :
coupling::control };
auto const couplingtype { ( auto *lookup {
( MoverParameters->TrainType == dt_EZT ) find_vehicle(
|| ( MoverParameters->TrainType == dt_DMU ) ) ? coupling,
coupling::permanent : []( TDynamicObject * vehicle ) {
coupling::control return ( vehicle->MoverParameters->Power > 1.0 ); } ) };
};
// try first to look towards the rear
auto *d = this; // zaczynamy od aktualnego
while( ( d = d->NextC( couplingtype ) ) != nullptr ) { return( lookup != nullptr ? lookup : this ); // always return valid vehicle for backward compatibility
if( d->MoverParameters->Power > 1.0 ) { }
return d;
TDynamicObject *
TDynamicObject::FindPantographCarrier() {
// try first within a single unit, broaden to all vehicles under our control if first attempt fails
std::array<coupling, 2> const couplings = { coupling::permanent, coupling::control };
for( auto const coupling : couplings ) {
auto *result =
find_vehicle(
coupling,
[]( TDynamicObject * vehicle ) {
return (
( vehicle->MoverParameters->EnginePowerSource.SourceType == TPowerSource::CurrentCollector )
&& ( vehicle->MoverParameters->EnginePowerSource.CollectorParameters.CollectorsNo > 0 ) ); } );
if( result != nullptr ) {
return result;
} }
} }
// if we didn't yet find a suitable vehicle try in the other direction // if we're still here, admit failure
d = this; // zaczynamy od aktualnego return nullptr;
}
while( ( d = d->PrevC( couplingtype ) ) != nullptr ) {
if( d->MoverParameters->Power > 1.0 ) {
return d;
}
}
// if we still don't have a match give up
return this;
};
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void TDynamicObject::ParamSet(int what, int into) void TDynamicObject::ParamSet(int what, int into)

View File

@@ -679,7 +679,11 @@ private:
void update_neighbours(); void update_neighbours();
// locates potential collision source within specified range, scanning its route in specified direction // locates potential collision source within specified range, scanning its route in specified direction
auto find_vehicle( int const Direction, double const Range ) const -> std::tuple<TDynamicObject *, int, double, bool>; auto find_vehicle( int const Direction, double const Range ) const -> std::tuple<TDynamicObject *, int, double, bool>;
TDynamicObject * ControlledFind(); // locates potential vehicle connected with specific coupling type and satisfying supplied predicate
template <typename Predicate_>
auto find_vehicle( coupling const Coupling, Predicate_ const Predicate ) -> TDynamicObject *;
TDynamicObject * FindPowered();
TDynamicObject * FindPantographCarrier();
void ParamSet(int what, int into); void ParamSet(int what, int into);
// zapytanie do AI, po którym segmencie skrzyżowania jechać // zapytanie do AI, po którym segmencie skrzyżowania jechać
int RouteWish(TTrack *tr); int RouteWish(TTrack *tr);
@@ -754,4 +758,25 @@ private:
erase_disabled(); erase_disabled();
}; };
template <typename Predicate_>
auto
TDynamicObject::find_vehicle( coupling const Coupling, Predicate_ const Predicate ) -> TDynamicObject * {
if( Predicate( this ) ) {
return this; }
// try first to look towards the rear
auto *vehicle { this };
while( ( vehicle = vehicle->NextC( Coupling ) ) != nullptr ) {
if( Predicate( vehicle ) ) {
return vehicle; } }
// if we didn't yet find a suitable vehicle try in the other direction
vehicle = this;
while( ( vehicle = vehicle->NextC( Coupling ) ) != nullptr ) {
if( Predicate( vehicle ) ) {
return vehicle; } }
// if we still don't have a match give up
return nullptr;
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -27,6 +27,12 @@ global_settings Global;
void void
global_settings::LoadIniFile(std::string asFileName) { global_settings::LoadIniFile(std::string asFileName) {
// initialize season data in case the main config file doesn't
std::time_t timenow = std::time( 0 );
std::tm *localtime = std::localtime( &timenow );
fMoveLight = localtime->tm_yday + 1; // numer bieżącego dnia w roku
simulation::Environment.compute_season( fMoveLight );
cParser parser(asFileName, cParser::buffer_FILE); cParser parser(asFileName, cParser::buffer_FILE);
ConfigParse(parser); ConfigParse(parser);
}; };
@@ -944,26 +950,8 @@ global_settings::ConfigParse(cParser &Parser) {
*/ */
if (iPause) if (iPause)
iTextMode = GLFW_KEY_F1; // jak pauza, to pokazać zegar iTextMode = GLFW_KEY_F1; // jak pauza, to pokazać zegar
/* this won't execute anymore with the old parser removed
// TBD: remove, or launch depending on passed flag?
if (qp)
{ // to poniżej wykonywane tylko raz, jedynie po wczytaniu eu07.ini*/
#ifdef _WIN32 #ifdef _WIN32
Console::ModeSet(iFeedbackMode, iFeedbackPort); // tryb pracy konsoli sterowniczej Console::ModeSet(iFeedbackMode, iFeedbackPort); // tryb pracy konsoli sterowniczej
#endif #endif
/*iFpsRadiusMax = 0.000025 * fFpsRadiusMax *
fFpsRadiusMax; // maksymalny promień renderowania 3000.0 -> 225
if (iFpsRadiusMax > 400)
iFpsRadiusMax = 400;
if (fDistanceFactor > 1.0)
{ // dla 1.0 specjalny tryb bez przeliczania
fDistanceFactor =
iWindowHeight /
fDistanceFactor; // fDistanceFactor>1.0 dla rozdzielczości większych niż bazowa
fDistanceFactor *=
(iMultisampling + 1.0) *
fDistanceFactor; // do kwadratu, bo większość odległości to ich kwadraty
}
}
*/
} }

View File

@@ -160,7 +160,10 @@ enum coupling {
mainhose = 0x20, mainhose = 0x20,
heating = 0x40, heating = 0x40,
permanent = 0x80, permanent = 0x80,
uic = 0x100 power24v = 0x100,
power110v = 0x200,
power3x400v = 0x400,
// uic = 0x1000,
}; };
// possible effect ranges for control commands; exclusive // possible effect ranges for control commands; exclusive
enum class range_t { enum class range_t {
@@ -180,11 +183,13 @@ enum class operation_t {
}; };
// start method for devices; exclusive // start method for devices; exclusive
enum class start_t { enum class start_t {
disabled,
manual, manual,
automatic, automatic,
manualwithautofallback, manualwithautofallback,
converter, converter,
battery battery,
direction
}; };
// recognized vehicle light locations and types; can be combined // recognized vehicle light locations and types; can be combined
enum light { enum light {
@@ -333,10 +338,10 @@ enum TProblem // lista problemów taboru, które uniemożliwiają jazdę
enum TCompressorList // lista parametrów w programatorze sprężarek enum TCompressorList // lista parametrów w programatorze sprężarek
{ // pozycje kolejne { // pozycje kolejne
cl_Allow = 0, // zezwolenie na pracę sprężarek cl_Allow = 0, // zezwolenie na pracę sprężarek
cl_SpeedFactor = 1, // mnożnik wydajności cl_SpeedFactor = 1, // mnożnik wydajności
cl_MinFactor = 2, // mnożnik progu załącznika ciśnieniowego cl_MinFactor = 2, // mnożnik progu załącznika ciśnieniowego
cl_MaxFactor = 3 // mnożnik progu wyłącznika ciśnieniowego cl_MaxFactor = 3 // mnożnik progu wyłącznika ciśnieniowego
}; };
struct TLocation struct TLocation
@@ -352,7 +357,7 @@ struct TRotation
double Ry; double Ry;
double Rz; double Rz;
}; };
/*wymiary*/
struct TDimension struct TDimension
{ {
double W = 0.0; double W = 0.0;
@@ -653,6 +658,7 @@ struct TSecuritySystem
int VelocityAllowed; int VelocityAllowed;
int NextVelocityAllowed; /*predkosc pokazywana przez sygnalizacje kabinowa*/ int NextVelocityAllowed; /*predkosc pokazywana przez sygnalizacje kabinowa*/
bool RadioStop; // czy jest RadioStop bool RadioStop; // czy jest RadioStop
bool PoweredUp { false }; // helper, for detection of power state change
inline bool is_beeping() const { inline bool is_beeping() const {
return TestFlag( Status, s_SHPalarm ); return TestFlag( Status, s_SHPalarm );
@@ -687,8 +693,10 @@ struct TCoupling {
double beta = 0.0; double beta = 0.0;
TCouplerType CouplerType = TCouplerType::NoCoupler; /*typ sprzegu*/ TCouplerType CouplerType = TCouplerType::NoCoupler; /*typ sprzegu*/
int AutomaticCouplingFlag = coupling::coupler; int AutomaticCouplingFlag = coupling::coupler;
int AllowedFlag = coupling::coupler | coupling::brakehose; //Ra: maska dostępnych int AllowedFlag = ( coupling::coupler | coupling::brakehose ); //Ra: maska dostępnych
int PowerFlag = ( coupling::power110v | coupling::power24v );
/*zmienne*/ /*zmienne*/
bool AutomaticCouplingAllowed { true }; // whether automatic coupling can be currently performed
int CouplingFlag = 0; /*0 - wirtualnie, 1 - sprzegi, 2 - pneumatycznie, 4 - sterowanie, 8 - kabel mocy*/ int CouplingFlag = 0; /*0 - wirtualnie, 1 - sprzegi, 2 - pneumatycznie, 4 - sterowanie, 8 - kabel mocy*/
class TMoverParameters *Connected = nullptr; /*co jest podlaczone*/ class TMoverParameters *Connected = nullptr; /*co jest podlaczone*/
int ConnectedNr = 0; //Ra: od której strony podłączony do (Connected): 0=przód, 1=tył int ConnectedNr = 0; //Ra: od której strony podłączony do (Connected): 0=przód, 1=tył
@@ -702,7 +710,8 @@ struct TCoupling {
TCouplerType adapter_type = TCouplerType::NoCoupler; // CouplerType override if other than NoCoupler TCouplerType adapter_type = TCouplerType::NoCoupler; // CouplerType override if other than NoCoupler
power_coupling power_high; power_coupling power_high;
// power_coupling power_low; // TODO: implement this power_coupling power_110v;
power_coupling power_24v;
int sounds { 0 }; // sounds emitted by the coupling devices int sounds { 0 }; // sounds emitted by the coupling devices
bool Render = false; /*ABu: czy rysowac jak zaczepiony sprzeg*/ bool Render = false; /*ABu: czy rysowac jak zaczepiony sprzeg*/
@@ -884,6 +893,7 @@ private:
bool auto_include_remote { false }; // automatic door closure applies also to remote control bool auto_include_remote { false }; // automatic door closure applies also to remote control
bool permit_needed { false }; bool permit_needed { false };
std::vector<int> permit_presets; // permit presets selectable with preset switch std::vector<int> permit_presets; // permit presets selectable with preset switch
float voltage { 0.f }; // power type required for door movement
// ld inputs // ld inputs
bool lock_enabled { true }; bool lock_enabled { true };
bool step_enabled { true }; bool step_enabled { true };
@@ -1013,6 +1023,7 @@ public:
double LightPower = 0.0; /*moc pobierana na ogrzewanie/oswietlenie*/ double LightPower = 0.0; /*moc pobierana na ogrzewanie/oswietlenie*/
double BatteryVoltage = 0.0; /*Winger - baterie w elektrykach*/ double BatteryVoltage = 0.0; /*Winger - baterie w elektrykach*/
bool Battery = false; /*Czy sa zalavzone baterie*/ bool Battery = false; /*Czy sa zalavzone baterie*/
start_t BatteryStart = start_t::manual;
bool EpFuse = true; /*Czy sa zalavzone baterie*/ bool EpFuse = true; /*Czy sa zalavzone baterie*/
bool Signalling = false; /*Czy jest zalaczona sygnalizacja hamowania ostatniego wagonu*/ bool Signalling = false; /*Czy jest zalaczona sygnalizacja hamowania ostatniego wagonu*/
bool Radio = true; /*Czy jest zalaczony radiotelefon*/ bool Radio = true; /*Czy jest zalaczony radiotelefon*/
@@ -1302,7 +1313,9 @@ public:
std::string Name; /*nazwa wlasna*/ std::string Name; /*nazwa wlasna*/
TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami
std::array<neighbour_data, 2> Neighbours; // potential collision sources std::array<neighbour_data, 2> Neighbours; // potential collision sources
bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/ bool Power110vIsAvailable = false; // cached availability of 110v power
bool Power24vIsAvailable = false; // cached availability of 110v power
bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/
int SoundFlag = 0; /*!o patrz stale sound_ */ int SoundFlag = 0; /*!o patrz stale sound_ */
int AIFlag{ 0 }; // HACK: events of interest for consist owner int AIFlag{ 0 }; // HACK: events of interest for consist owner
double DistCounter = 0.0; /*! licznik kilometrow */ double DistCounter = 0.0; /*! licznik kilometrow */
@@ -1365,6 +1378,8 @@ public:
bool ConverterAllow = false; /*zezwolenie na prace przetwornicy NBMX*/ bool ConverterAllow = false; /*zezwolenie na prace przetwornicy NBMX*/
bool ConverterAllowLocal{ true }; // local device state override (most units don't have this fitted so it's set to true not to intefere) bool ConverterAllowLocal{ true }; // local device state override (most units don't have this fitted so it's set to true not to intefere)
bool ConverterFlag = false; /*! czy wlaczona przetwornica NBMX*/ bool ConverterFlag = false; /*! czy wlaczona przetwornica NBMX*/
start_t ConverterOverloadRelayStart { start_t::manual }; // whether overload relay reset responds to dedicated button
bool ConverterOverloadRelayOffWhenMainIsOff { false };
fuel_pump FuelPump; fuel_pump FuelPump;
oil_pump OilPump; oil_pump OilPump;
water_pump WaterPump; water_pump WaterPump;
@@ -1482,6 +1497,7 @@ public:
bool NoVoltRelay{ true }; // switches off if the power level drops below threshold bool NoVoltRelay{ true }; // switches off if the power level drops below threshold
bool OvervoltageRelay{ true }; // switches off if the power level goes above threshold bool OvervoltageRelay{ true }; // switches off if the power level goes above threshold
bool s_CAtestebrake = false; //hunter-091012: zmienna dla testu ca bool s_CAtestebrake = false; //hunter-091012: zmienna dla testu ca
std::array<std::pair<double, double>, 4> PowerCircuits; //24v, 110v, 3x400v and 3000v power circuits, voltage from local sources and current draw pairs
/*-zmienne dla lokomotywy spalinowej z przekladnia mechaniczna*/ /*-zmienne dla lokomotywy spalinowej z przekladnia mechaniczna*/
double dizel_fill = 0.0; /*napelnienie*/ double dizel_fill = 0.0; /*napelnienie*/
@@ -1612,7 +1628,7 @@ public:
// Q ******************************************************************************************* // Q *******************************************************************************************
double GetTrainsetVoltage( int const Coupling = ( coupling::heating | coupling::highvoltage ) ) const; double GetTrainsetVoltage( int const Coupling = ( coupling::heating | coupling::highvoltage ) ) const;
double GetAnyTrainsetVoltage() const; double GetTrainsetHighVoltage() const;
bool switch_physics(bool const State); bool switch_physics(bool const State);
double LocalBrakeRatio(void); double LocalBrakeRatio(void);
double ManualBrakeRatio(void); double ManualBrakeRatio(void);
@@ -1657,7 +1673,7 @@ public:
bool SecuritySystemReset(void); bool SecuritySystemReset(void);
void SecuritySystemCheck(double dt); void SecuritySystemCheck(double dt);
bool BatterySwitch(bool State); bool BatterySwitch( bool State, range_t const Notify = range_t::consist );
bool EpFuseSwitch(bool State); bool EpFuseSwitch(bool State);
bool SpringBrakeActivate(bool State); bool SpringBrakeActivate(bool State);
bool SpringBrakeShutOff(bool State); bool SpringBrakeShutOff(bool State);
@@ -1735,7 +1751,7 @@ public:
/*-funkcje typowe dla lokomotywy elektrycznej*/ /*-funkcje typowe dla lokomotywy elektrycznej*/
void LowVoltagePowerCheck( double const Deltatime ); void LowVoltagePowerCheck( double const Deltatime );
void MainsCheck( double const Deltatime ); void MainsCheck( double const Deltatime );
void PowerCouplersCheck( double const Deltatime ); void PowerCouplersCheck( double const Deltatime, coupling const Coupling );
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 );
@@ -1749,7 +1765,7 @@ public:
bool FuseFlagCheck(void) const; // sprawdzanie flagi nadmiarowego bool FuseFlagCheck(void) const; // sprawdzanie flagi nadmiarowego
void FuseOff(void); // wylaczenie nadmiarowego void FuseOff(void); // wylaczenie nadmiarowego
bool UniversalResetButton( int const Button, range_t const Notify = range_t::consist ); bool UniversalResetButton( int const Button, range_t const Notify = range_t::consist );
bool RelayReset( int const Relays ); // resets specified relays bool RelayReset( int const Relays, range_t const Notify = range_t::consist ); // resets specified relays
double ShowCurrent( int AmpN ) const; //pokazuje bezwgl. wartosc pradu na wybranym amperomierzu double ShowCurrent( int AmpN ) const; //pokazuje bezwgl. wartosc pradu na wybranym amperomierzu
double ShowCurrentP(int AmpN) const; //pokazuje bezwgl. wartosc pradu w wybranym pojezdzie //Q 20160722 double ShowCurrentP(int AmpN) const; //pokazuje bezwgl. wartosc pradu w wybranym pojezdzie //Q 20160722

File diff suppressed because it is too large Load Diff

View File

@@ -970,6 +970,11 @@ void TEStEP1::EPCalc(double dt)
LBP = LBP - dv; LBP = LBP - dv;
} }
void TEStEP1::SetEPS( double const nEPS )
{
EPS = nEPS;
}
//---EST3-- //---EST3--
double TESt3::GetPF( double const PP, double const dt, double const Vel ) double TESt3::GetPF( double const PP, double const dt, double const Vel )

View File

@@ -418,6 +418,7 @@ class TEStEP1 : public TEStEP2 {
public: public:
void EPCalc(double dt); void EPCalc(double dt);
void SetEPS( double const nEPS ) override; //stan hamulca EP
inline TEStEP1(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) : inline TEStEP1(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) :
TEStEP2(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa) TEStEP2(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)

293
Train.cpp
View File

@@ -545,14 +545,14 @@ dictionary_source *TTrain::GetTrainState() {
dict->insert( "name", DynamicObject->asName ); dict->insert( "name", DynamicObject->asName );
dict->insert( "cab", mvOccupied->CabOccupied ); dict->insert( "cab", mvOccupied->CabOccupied );
// basic systems state data // basic systems state data
dict->insert( "battery", mvControlled->Battery ); dict->insert( "battery", mvOccupied->Power24vIsAvailable );
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_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( "main_ready", ( false == mvControlled->Mains ) && ( fHVoltage > 0.0 ) && ( mvControlled->MainsInitTimeCountdown <= 0.0 ) );
dict->insert( "converter", mvControlled->ConverterFlag ); dict->insert( "converter", mvOccupied->Power110vIsAvailable );
dict->insert( "converter_overload", mvControlled->ConvOvldFlag ); dict->insert( "converter_overload", mvControlled->ConvOvldFlag );
dict->insert( "compress", mvControlled->CompressorFlag ); dict->insert( "compress", mvControlled->CompressorFlag );
dict->insert( "pant_compressor", mvControlled->PantCompFlag ); dict->insert( "pant_compressor", mvPantographUnit->PantCompFlag );
dict->insert( "lights_front", mvOccupied->iLights[ end::front ] ); dict->insert( "lights_front", mvOccupied->iLights[ end::front ] );
dict->insert( "lights_rear", mvOccupied->iLights[ end::rear ] ); dict->insert( "lights_rear", mvOccupied->iLights[ end::rear ] );
dict->insert( "lights_compartments", mvOccupied->CompartmentLights.is_active || mvOccupied->CompartmentLights.is_disabled ); dict->insert( "lights_compartments", mvOccupied->CompartmentLights.is_active || mvOccupied->CompartmentLights.is_disabled );
@@ -606,7 +606,7 @@ dictionary_source *TTrain::GetTrainState() {
dict->insert( "ca", TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) ); dict->insert( "ca", TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) );
dict->insert( "shp", TestFlag( mvOccupied->SecuritySystem.Status, s_active ) ); dict->insert( "shp", TestFlag( mvOccupied->SecuritySystem.Status, s_active ) );
dict->insert( "distance_counter", m_distancecounter ); dict->insert( "distance_counter", m_distancecounter );
dict->insert( "pantpress", std::abs( mvControlled->PantPress ) ); dict->insert( "pantpress", std::abs( mvPantographUnit->PantPress ) );
dict->insert( "universal3", InstrumentLightActive ); dict->insert( "universal3", InstrumentLightActive );
dict->insert( "radio_channel", RadioChannel() ); dict->insert( "radio_channel", RadioChannel() );
dict->insert( "radio_volume", Global.RadioVolume ); dict->insert( "radio_volume", Global.RadioVolume );
@@ -617,7 +617,7 @@ dictionary_source *TTrain::GetTrainState() {
dict->insert( "slipping_wheels", mvOccupied->SlippingWheels ); dict->insert( "slipping_wheels", mvOccupied->SlippingWheels );
dict->insert( "sanding", mvOccupied->SandDose ); dict->insert( "sanding", mvOccupied->SandDose );
// electric current data // electric current data
dict->insert( "traction_voltage", std::abs( mvControlled->PantographVoltage ) ); dict->insert( "traction_voltage", std::abs( mvPantographUnit->PantographVoltage ) );
dict->insert( "voltage", std::abs( mvControlled->EngineVoltage ) ); dict->insert( "voltage", std::abs( mvControlled->EngineVoltage ) );
dict->insert( "im", std::abs( mvControlled->Im ) ); dict->insert( "im", std::abs( mvControlled->Im ) );
dict->insert( "fuse", mvControlled->FuseFlag ); dict->insert( "fuse", mvControlled->FuseFlag );
@@ -745,7 +745,7 @@ bool TTrain::is_eztoer() const {
return return
( ( mvControlled->TrainType == dt_EZT ) ( ( mvControlled->TrainType == dt_EZT )
&& ( mvOccupied->BrakeSubsystem == TBrakeSubSystem::ss_ESt ) && ( mvOccupied->BrakeSubsystem == TBrakeSubSystem::ss_ESt )
&& ( mvControlled->Battery == true ) && ( mvControlled->Power24vIsAvailable == true )
&& ( mvControlled->EpFuse == true ) && ( mvControlled->EpFuse == true )
&& ( mvControlled->DirActive != 0 ) ); // od yB && ( mvControlled->DirActive != 0 ) ); // od yB
} }
@@ -2068,7 +2068,7 @@ void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command
if( Command.action != GLFW_REPEAT ) { if( Command.action != GLFW_REPEAT ) {
// keep the switch from flipping back and forth if key is held down // keep the switch from flipping back and forth if key is held down
if( false == Train->mvOccupied->Battery ) { if( false == Train->mvOccupied->Power24vIsAvailable ) {
// turn on // turn on
OnCommand_batteryenable( Train, Command ); OnCommand_batteryenable( Train, Command );
} }
@@ -2086,18 +2086,11 @@ void TTrain::OnCommand_batteryenable( TTrain *Train, command_data const &Command
Train->ggBatteryButton.UpdateValue( 1.0f, Train->dsbSwitch ); Train->ggBatteryButton.UpdateValue( 1.0f, Train->dsbSwitch );
Train->ggBatteryOnButton.UpdateValue( 1.0f, Train->dsbSwitch ); Train->ggBatteryOnButton.UpdateValue( 1.0f, Train->dsbSwitch );
if( true == Train->mvOccupied->Battery ) { return; } // already on Train->mvOccupied->BatterySwitch( true );
if( Train->mvOccupied->BatterySwitch( true ) ) { // side-effects
// side-effects if( Train->mvOccupied->LightsPosNo > 0 ) {
if( Train->mvOccupied->LightsPosNo > 0 ) { Train->SetLights();
Train->SetLights();
}
if( TestFlag( Train->mvOccupied->SecuritySystem.SystemType, 2 ) ) {
// Ra: znowu w kabinie jest coś, co być nie powinno!
SetFlag( Train->mvOccupied->SecuritySystem.Status, s_active );
SetFlag( Train->mvOccupied->SecuritySystem.Status, s_SHPalarm );
}
} }
} }
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
@@ -2116,8 +2109,6 @@ void TTrain::OnCommand_batterydisable( TTrain *Train, command_data const &Comman
Train->ggBatteryButton.UpdateValue( 0.0f, Train->dsbSwitch ); Train->ggBatteryButton.UpdateValue( 0.0f, Train->dsbSwitch );
Train->ggBatteryOffButton.UpdateValue( 1.0f, Train->dsbSwitch ); Train->ggBatteryOffButton.UpdateValue( 1.0f, Train->dsbSwitch );
if( false == Train->mvOccupied->Battery ) { return; } // already off
Train->mvOccupied->BatterySwitch( false ); Train->mvOccupied->BatterySwitch( false );
} }
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
@@ -2136,7 +2127,7 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
auto const &pantograph { Train->mvControlled->Pantographs[ end::front ] }; auto const &pantograph { Train->mvPantographUnit->Pantographs[ end::front ] };
auto const state { auto const state {
pantograph.valve.is_enabled pantograph.valve.is_enabled
|| pantograph.is_active }; // fallback for impulse switches || pantograph.is_active }; // fallback for impulse switches
@@ -2150,7 +2141,7 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
// impulse switches return automatically to neutral position // impulse switches return automatically to neutral position
if( Train->mvOccupied->PantSwitchType == "impulse" ) { if( Train->mvOccupied->PantSwitchType == "impulse" ) {
Train->mvControlled->OperatePantographValve( end::front, operation_t::none ); Train->mvOccupied->OperatePantographValve( end::front, operation_t::none );
} }
} }
} }
@@ -2162,7 +2153,7 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
auto const &pantograph { Train->mvControlled->Pantographs[ end::rear ] }; auto const &pantograph { Train->mvPantographUnit->Pantographs[ end::rear ] };
auto const state { auto const state {
pantograph.valve.is_enabled pantograph.valve.is_enabled
|| pantograph.is_active }; // fallback for impulse switches || pantograph.is_active }; // fallback for impulse switches
@@ -2176,7 +2167,7 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
// impulse switches return automatically to neutral position // impulse switches return automatically to neutral position
if( Train->mvOccupied->PantSwitchType == "impulse" ) { if( Train->mvOccupied->PantSwitchType == "impulse" ) {
Train->mvControlled->OperatePantographValve( end::rear, operation_t::none ); Train->mvOccupied->OperatePantographValve( end::rear, operation_t::none );
} }
} }
} }
@@ -2191,7 +2182,7 @@ void TTrain::OnCommand_pantographraisefront( TTrain *Train, command_data const &
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
Train->mvControlled->OperatePantographValve( end::front, Train->mvOccupied->OperatePantographValve( end::front,
Train->mvOccupied->PantSwitchType == "impulse" ? Train->mvOccupied->PantSwitchType == "impulse" ?
operation_t::enable_on : operation_t::enable_on :
operation_t::enable ); operation_t::enable );
@@ -2212,7 +2203,7 @@ void TTrain::OnCommand_pantographraiserear( TTrain *Train, command_data const &C
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
Train->mvControlled->OperatePantographValve( end::rear, Train->mvOccupied->OperatePantographValve( end::rear,
Train->mvOccupied->PantSwitchType == "impulse" ? Train->mvOccupied->PantSwitchType == "impulse" ?
operation_t::enable_on : operation_t::enable_on :
operation_t::enable ); operation_t::enable );
@@ -2238,7 +2229,7 @@ void TTrain::OnCommand_pantographlowerfront( TTrain *Train, command_data const &
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
Train->mvControlled->OperatePantographValve( end::front, Train->mvOccupied->OperatePantographValve( end::front,
Train->mvOccupied->PantSwitchType == "impulse" ? Train->mvOccupied->PantSwitchType == "impulse" ?
operation_t::disable_on : operation_t::disable_on :
operation_t::disable ); operation_t::disable );
@@ -2263,7 +2254,7 @@ void TTrain::OnCommand_pantographlowerrear( TTrain *Train, command_data const &C
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
Train->mvControlled->OperatePantographValve( end::rear, Train->mvOccupied->OperatePantographValve( end::rear,
Train->mvOccupied->PantSwitchType == "impulse" ? Train->mvOccupied->PantSwitchType == "impulse" ?
operation_t::disable_on : operation_t::disable_on :
operation_t::disable ); operation_t::disable );
@@ -2289,9 +2280,9 @@ void TTrain::OnCommand_pantographlowerall( TTrain *Train, command_data const &Co
if( Train->ggPantAllDownButton.type() == TGaugeType::toggle ) { if( Train->ggPantAllDownButton.type() == TGaugeType::toggle ) {
// two-state switch, only cares about press events // two-state switch, only cares about press events
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
Train->mvControlled->DropAllPantographs( false == Train->mvControlled->PantAllDown ); Train->mvPantographUnit->DropAllPantographs( false == Train->mvPantographUnit->PantAllDown );
// visual feedback // visual feedback
Train->ggPantAllDownButton.UpdateValue( ( Train->mvControlled->PantAllDown ? 1.0 : 0.0 ), Train->dsbSwitch ); Train->ggPantAllDownButton.UpdateValue( ( Train->mvPantographUnit->PantAllDown ? 1.0 : 0.0 ), Train->dsbSwitch );
} }
} }
else { else {
@@ -2327,8 +2318,8 @@ void TTrain::OnCommand_pantographtoggleselected( TTrain *Train, command_data con
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
auto const state { auto const state {
Train->mvControlled->PantsValve.is_enabled Train->mvPantographUnit->PantsValve.is_enabled
| Train->mvControlled->PantsValve.is_active }; // fallback for impulse switches | Train->mvPantographUnit->PantsValve.is_active }; // fallback for impulse switches
if( state ) { if( state ) {
OnCommand_pantographlowerselected( Train, Command ); OnCommand_pantographlowerselected( Train, Command );
} }
@@ -2341,12 +2332,12 @@ void TTrain::OnCommand_pantographtoggleselected( TTrain *Train, command_data con
if( Train->m_controlmapper.contains( "pantselectedoff_sw:" ) ) { if( Train->m_controlmapper.contains( "pantselectedoff_sw:" ) ) {
// two buttons setup // two buttons setup
if( Train->ggPantSelectedButton.type() != TGaugeType::toggle ) { if( Train->ggPantSelectedButton.type() != TGaugeType::toggle ) {
Train->mvControlled->OperatePantographsValve( operation_t::enable_off ); Train->mvOccupied->OperatePantographsValve( operation_t::enable_off );
// visual feedback // visual feedback
Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch ); Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch );
} }
if( Train->ggPantSelectedDownButton.type() != TGaugeType::toggle ) { if( Train->ggPantSelectedDownButton.type() != TGaugeType::toggle ) {
Train->mvControlled->OperatePantographsValve( operation_t::disable_off ); Train->mvOccupied->OperatePantographsValve( operation_t::disable_off );
// visual feedback // visual feedback
Train->ggPantSelectedDownButton.UpdateValue( 0.0, Train->dsbSwitch ); Train->ggPantSelectedDownButton.UpdateValue( 0.0, Train->dsbSwitch );
} }
@@ -2355,7 +2346,7 @@ void TTrain::OnCommand_pantographtoggleselected( TTrain *Train, command_data con
if( Train->ggPantSelectedButton.type() != TGaugeType::toggle ) { if( Train->ggPantSelectedButton.type() != TGaugeType::toggle ) {
// special case, just one impulse switch controlling both states // special case, just one impulse switch controlling both states
// with neutral position mid-way // with neutral position mid-way
Train->mvControlled->OperatePantographsValve( operation_t::none ); Train->mvOccupied->OperatePantographsValve( operation_t::none );
// visual feedback // visual feedback
Train->ggPantSelectedButton.UpdateValue( 0.5, Train->dsbSwitch ); Train->ggPantSelectedButton.UpdateValue( 0.5, Train->dsbSwitch );
} }
@@ -2369,7 +2360,7 @@ void TTrain::OnCommand_pantographraiseselected( TTrain *Train, command_data cons
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// raise selected // raise selected
Train->mvControlled->OperatePantographsValve( Train->mvOccupied->OperatePantographsValve(
Train->ggPantSelectedButton.type() != TGaugeType::toggle ? Train->ggPantSelectedButton.type() != TGaugeType::toggle ?
operation_t::enable_on : operation_t::enable_on :
operation_t::enable ); operation_t::enable );
@@ -2388,7 +2379,7 @@ void TTrain::OnCommand_pantographlowerselected( TTrain *Train, command_data cons
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// lower selected // lower selected
Train->mvControlled->OperatePantographsValve( Train->mvOccupied->OperatePantographsValve(
Train->ggPantSelectedDownButton.type() != TGaugeType::toggle ? Train->ggPantSelectedDownButton.type() != TGaugeType::toggle ?
operation_t::disable_on : operation_t::disable_on :
operation_t::disable ); operation_t::disable );
@@ -2424,8 +2415,8 @@ void TTrain::change_pantograph_selection( int const Change ) {
auto const frontstate{ ( m_pantselection == 2 ) || ( m_pantselection == ( swapends ? 1 : 3 ) ) }; auto const frontstate{ ( m_pantselection == 2 ) || ( m_pantselection == ( swapends ? 1 : 3 ) ) };
auto const rearstate{ ( m_pantselection == 2 ) || ( m_pantselection == ( swapends ? 3 : 1 ) ) }; auto const rearstate{ ( m_pantselection == 2 ) || ( m_pantselection == ( swapends ? 3 : 1 ) ) };
// potentially adjust pantograph valves // potentially adjust pantograph valves
mvControlled->OperatePantographValve( end::front, ( frontstate ? operation_t::enable : operation_t::disable ) ); mvOccupied->OperatePantographValve( end::front, ( frontstate ? operation_t::enable : operation_t::disable ) );
mvControlled->OperatePantographValve( end::rear, ( rearstate ? operation_t::enable : operation_t::disable ) ); mvOccupied->OperatePantographValve( end::rear, ( rearstate ? operation_t::enable : operation_t::disable ) );
} }
void TTrain::OnCommand_pantographcompressorvalvetoggle( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_pantographcompressorvalvetoggle( TTrain *Train, command_data const &Command ) {
@@ -2489,7 +2480,7 @@ void TTrain::OnCommand_pantographcompressoractivate( TTrain *Train, command_data
if( ( Train->ggPantCompressorValve.SubModel == nullptr ) if( ( Train->ggPantCompressorValve.SubModel == nullptr )
&& ( Train->mvControlled->TrainType == dt_EZT ? && ( Train->mvControlled->TrainType == dt_EZT ?
( Train->mvControlled != Train->mvOccupied ) : ( Train->mvOccupied == Train->mvPantographUnit ) :
( Train->iCabn != 0 ) ) ) { ( Train->iCabn != 0 ) ) ) {
// tylko w maszynowym // tylko w maszynowym
return; return;
@@ -2497,17 +2488,17 @@ void TTrain::OnCommand_pantographcompressoractivate( TTrain *Train, command_data
if( Command.action != GLFW_RELEASE ) { if( Command.action != GLFW_RELEASE ) {
// press or hold to activate // press or hold to activate
if( ( Train->mvControlled->PantPress < 4.8 ) if( ( Train->mvPantographUnit->PantPress < 4.8 )
&& ( true == Train->mvControlled->Battery ) ) { && ( true == Train->mvPantographUnit->Power24vIsAvailable ) ) {
// needs live power source and low enough pressure to work // needs live power source and low enough pressure to work
Train->mvControlled->PantCompFlag = true; Train->mvPantographUnit->PantCompFlag = true;
} }
// visual feedback // visual feedback
Train->ggPantCompressorButton.UpdateValue( 1.0 ); Train->ggPantCompressorButton.UpdateValue( 1.0 );
} }
else { else {
// release to disable // release to disable
Train->mvControlled->PantCompFlag = false; Train->mvPantographUnit->PantCompFlag = false;
// visual feedback // visual feedback
Train->ggPantCompressorButton.UpdateValue( 0.0 ); Train->ggPantCompressorButton.UpdateValue( 0.0 );
} }
@@ -3021,7 +3012,7 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
if( ( false == Train->mvControlled->ConverterAllow ) if( ( false == Train->mvOccupied->Power110vIsAvailable )
&& ( Train->ggConverterButton.GetValue() < 0.5 ) ) { && ( Train->ggConverterButton.GetValue() < 0.5 ) ) {
// turn on // turn on
OnCommand_converterenable( Train, Command ); OnCommand_converterenable( Train, Command );
@@ -3043,30 +3034,16 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma
void TTrain::OnCommand_converterenable( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_converterenable( TTrain *Train, command_data const &Command ) {
if( Train->mvControlled->ConverterStart == start_t::automatic ) {
// let the automatic thing do its automatic thing...
return;
}
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// visual feedback // visual feedback
Train->ggConverterButton.UpdateValue( 1.0, Train->dsbSwitch ); Train->ggConverterButton.UpdateValue( 1.0, Train->dsbSwitch );
if( true == Train->mvControlled->ConverterAllow ) { return; } // already enabled
// impulse type switch has no effect if there's no power // impulse type switch has no effect if there's no power
// NOTE: this is most likely setup wrong, but the whole thing is smoke and mirrors anyway // NOTE: this is most likely setup wrong, but the whole thing is smoke and mirrors anyway
if( ( Train->mvOccupied->ConvSwitchType != "impulse" ) if( ( Train->mvOccupied->ConvSwitchType != "impulse" )
|| ( Train->mvControlled->Mains ) ) { || ( Train->mvControlled->Mains ) ) {
// won't start if the line breaker button is still held // won't start if the line breaker button is still held
if( true == Train->mvControlled->ConverterSwitch( true ) ) { Train->mvOccupied->ConverterSwitch( true );
// side effects
// control the compressor, if it's paired with the converter
if( Train->mvControlled->CompressorPower == 2 ) {
// hunter-091012: tak jest poprawnie
Train->mvControlled->CompressorSwitch( true );
}
}
} }
} }
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
@@ -3077,11 +3054,6 @@ void TTrain::OnCommand_converterenable( TTrain *Train, command_data const &Comma
void TTrain::OnCommand_converterdisable( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_converterdisable( TTrain *Train, command_data const &Command ) {
if( Train->mvControlled->ConverterStart == start_t::automatic ) {
// let the automatic thing do its automatic thing...
return;
}
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// visual feedback // visual feedback
Train->ggConverterButton.UpdateValue( 0.0, Train->dsbSwitch ); Train->ggConverterButton.UpdateValue( 0.0, Train->dsbSwitch );
@@ -3089,20 +3061,7 @@ void TTrain::OnCommand_converterdisable( TTrain *Train, command_data const &Comm
Train->ggConverterOffButton.UpdateValue( 1.0, Train->dsbSwitch ); Train->ggConverterOffButton.UpdateValue( 1.0, Train->dsbSwitch );
} }
if( false == Train->mvControlled->ConverterAllow ) { return; } // already disabled Train->mvOccupied->ConverterSwitch( false );
if( true == Train->mvControlled->ConverterSwitch( false ) ) {
// side effects
// control the compressor, if it's paired with the converter
if( Train->mvControlled->CompressorPower == 2 ) {
// hunter-091012: tak jest poprawnie
Train->mvControlled->CompressorSwitch( false );
}
if( ( Train->mvControlled->TrainType == dt_EZT )
&& ( false == TestFlag( Train->mvControlled->EngDmgFlag, 4 ) ) ) {
Train->mvControlled->ConvOvldFlag = false;
}
}
} }
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
// potentially reset impulse switch position, using shared code branch // potentially reset impulse switch position, using shared code branch
@@ -3190,7 +3149,12 @@ void TTrain::OnCommand_compressortoggle( TTrain *Train, command_data const &Comm
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
if( false == Train->mvControlled->CompressorAllow ) { auto const compressorisenabled { (
Train->Dynamic()->Mechanik ?
Train->Dynamic()->Mechanik->IsAnyCompressorEnabled :
Train->mvOccupied->CompressorAllow ) };
if( false == compressorisenabled ) {
// turn on // turn on
OnCommand_compressorenable( Train, Command ); OnCommand_compressorenable( Train, Command );
} }
@@ -3214,22 +3178,16 @@ void TTrain::OnCommand_compressortoggle( TTrain *Train, command_data const &Comm
void TTrain::OnCommand_compressorenable( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_compressorenable( TTrain *Train, command_data const &Command ) {
if( Train->mvControlled->CompressorPower >= 2 ) {
return;
}
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// visual feedback // visual feedback
Train->ggCompressorButton.UpdateValue( 1.0, Train->dsbSwitch ); Train->ggCompressorButton.UpdateValue( 1.0, Train->dsbSwitch );
if( true == Train->mvControlled->CompressorAllow ) { return; } // already enabled
// impulse type switch has no effect if there's no power // impulse type switch has no effect if there's no power
// NOTE: this is most likely setup wrong, but the whole thing is smoke and mirrors anyway // NOTE: this is most likely setup wrong, but the whole thing is smoke and mirrors anyway
// if( ( Train->mvOccupied->CompSwitchType != "impulse" ) // if( ( Train->mvOccupied->CompSwitchType != "impulse" )
// || ( Train->mvControlled->Mains ) ) { // || ( Train->mvControlled->Mains ) ) {
Train->mvControlled->CompressorSwitch( true ); Train->mvOccupied->CompressorSwitch( true );
// } // }
} }
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
@@ -3251,9 +3209,7 @@ void TTrain::OnCommand_compressordisable( TTrain *Train, command_data const &Com
Train->ggCompressorOffButton.UpdateValue( 1.0, Train->dsbSwitch ); Train->ggCompressorOffButton.UpdateValue( 1.0, Train->dsbSwitch );
} }
*/ */
if( false == Train->mvControlled->CompressorAllow ) { return; } // already disabled Train->mvOccupied->CompressorSwitch( false );
Train->mvControlled->CompressorSwitch( false );
} }
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
// potentially reset impulse switch position, using shared code branch // potentially reset impulse switch position, using shared code branch
@@ -5695,7 +5651,7 @@ void TTrain::OnCommand_radiostopsend( TTrain *Train, command_data const &Command
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
if( ( true == Train->mvOccupied->Radio ) if( ( true == Train->mvOccupied->Radio )
&& ( Train->mvControlled->Battery || Train->mvControlled->ConverterFlag ) ) { && ( Train->mvOccupied->Power24vIsAvailable || Train->mvOccupied->Power110vIsAvailable ) ) {
simulation::Region->RadioStop( Train->Dynamic()->GetPosition() ); simulation::Region->RadioStop( Train->Dynamic()->GetPosition() );
} }
// visual feedback // visual feedback
@@ -5712,7 +5668,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 ) && ( true == Train->mvOccupied->Radio )
&& ( Train->mvControlled->Battery || Train->mvControlled->ConverterFlag ) ) { && ( Train->mvOccupied->Power24vIsAvailable || Train->mvOccupied->Power110vIsAvailable ) ) {
Train->Dynamic()->RadioStop(); Train->Dynamic()->RadioStop();
} }
// visual feedback // visual feedback
@@ -5729,7 +5685,7 @@ void TTrain::OnCommand_radiocall3send( TTrain *Train, command_data const &Comman
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
if( ( Train->RadioChannel() != 10 ) if( ( Train->RadioChannel() != 10 )
&& ( true == Train->mvOccupied->Radio ) && ( true == Train->mvOccupied->Radio )
&& ( Train->mvControlled->Battery || Train->mvControlled->ConverterFlag ) ) { && ( Train->mvOccupied->Power24vIsAvailable || Train->mvOccupied->Power110vIsAvailable) ) {
simulation::Events.queue_receivers( radio_message::call3, Train->Dynamic()->GetPosition() ); simulation::Events.queue_receivers( radio_message::call3, Train->Dynamic()->GetPosition() );
} }
// visual feedback // visual feedback
@@ -5912,13 +5868,7 @@ bool TTrain::Update( double const Deltatime )
|| ( ( ggMainOnButton.SubModel != nullptr ) && ( ggMainOnButton.GetDesiredValue() > 0.95 ) || ( ( ggMainOnButton.SubModel != nullptr ) && ( ggMainOnButton.GetDesiredValue() > 0.95 )
|| ( ggIgnitionKey.GetDesiredValue() > 0.95 ) ) ) { // HACK: fallback || ( ggIgnitionKey.GetDesiredValue() > 0.95 ) ) ) { // HACK: fallback
// 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( ( mvControlled->MainSwitchCheck() ) if( mvControlled->MainSwitchCheck() ) {
&& ( ( fHVoltage > 0.5 * mvControlled->EnginePowerSource.MaxVoltage )
|| ( ( mvControlled->EngineType != TEngineType::ElectricSeriesMotor )
&& ( mvControlled->EngineType != TEngineType::ElectricInductionMotor )
&& ( true == mvControlled->Battery ) ) ) ) {
// prevent the switch from working if there's no power
// TODO: consider whether it makes sense for diesel engines and such
fMainRelayTimer += Deltatime; fMainRelayTimer += Deltatime;
} }
} }
@@ -6034,7 +5984,7 @@ bool TTrain::Update( double const Deltatime )
&& ( mvControlled->EngineType != TEngineType::ElectricInductionMotor ) ) { // Ra 2014-09: czy taki rozdzia? ma sens? && ( mvControlled->EngineType != TEngineType::ElectricInductionMotor ) ) { // Ra 2014-09: czy taki rozdzia? ma sens?
fHVoltage = std::max( fHVoltage = std::max(
mvControlled->PantographVoltage, mvControlled->PantographVoltage,
mvControlled->GetAnyTrainsetVoltage() ); // Winger czy to nie jest zle? mvControlled->GetTrainsetHighVoltage() ); // Winger czy to nie jest zle?
} }
// *mvControlled->Mains); // *mvControlled->Mains);
else { else {
@@ -6253,7 +6203,7 @@ bool TTrain::Update( double const Deltatime )
else else
fConverterTimer = 0; fConverterTimer = 0;
//------------------ //------------------
auto const lowvoltagepower { mvControlled->Battery || mvControlled->ConverterFlag }; auto const lowvoltagepower { mvOccupied->Power24vIsAvailable || mvOccupied->Power110vIsAvailable };
// youBy - prad w drugim czlonie: galaz lub calosc // youBy - prad w drugim czlonie: galaz lub calosc
{ {
@@ -6356,11 +6306,11 @@ bool TTrain::Update( double const Deltatime )
// TODO: implement object-based circuits and power systems model so we can have this working more properly // TODO: implement object-based circuits and power systems model so we can have this working more properly
ggLVoltage.UpdateValue( ggLVoltage.UpdateValue(
std::max( std::max(
( mvControlled->ConverterFlag ? ( mvOccupied->Power110vIsAvailable ?
mvControlled->NominalBatteryVoltage : mvOccupied->NominalBatteryVoltage :
0.0 ), 0.0 ),
( mvControlled->Battery ? ( mvOccupied->Power24vIsAvailable ?
mvControlled->BatteryVoltage : mvOccupied->BatteryVoltage :
0.0 ) ) ); 0.0 ) ) );
ggLVoltage.Update(); ggLVoltage.Update();
} }
@@ -6468,9 +6418,9 @@ bool TTrain::Update( double const Deltatime )
false : false :
true ) ); true ) );
btLampkaPrzetw.Turn( mvControlled->ConverterFlag ); btLampkaPrzetw.Turn( mvOccupied->Power110vIsAvailable );
btLampkaPrzetwOff.Turn( false == mvControlled->ConverterFlag ); btLampkaPrzetwOff.Turn( false == mvOccupied->Power110vIsAvailable );
btLampkaNadmPrzetw.Turn( mvControlled->ConvOvldFlag ); btLampkaNadmPrzetw.Turn( Dynamic()->Mechanik ? Dynamic()->Mechanik->IsAnyConverterOverloadRelayOpen : mvControlled->ConvOvldFlag );
btLampkaOpory.Turn( btLampkaOpory.Turn(
mvControlled->StLinFlag ? mvControlled->StLinFlag ?
@@ -6721,7 +6671,15 @@ bool TTrain::Update( double const Deltatime )
btLampkaStycznB.Turn( true ); // mozna prowadzic rozruch btLampkaStycznB.Turn( true ); // mozna prowadzic rozruch
} }
// hunter-271211: sygnalizacja poslizgu w pierwszym pojezdzie, gdy wystapi w drugim // hunter-271211: sygnalizacja poslizgu w pierwszym pojezdzie, gdy wystapi w drugim
btLampkaPoslizg.Turn( mover->SlippingWheels ); if( mover->SlippingWheels ) {
// Ra 2014-12: lokomotywy 181/182 dostają SlippingWheels po zahamowaniu powyżej 2.85 bara i buczały
auto const veldiff { ( DynamicObject->GetVelocity() - fTachoVelocity ) / mvControlled->Vmax };
if( veldiff < -0.01 ) {
// 1% Vmax rezerwy, żeby 181/182 nie buczały po zahamowaniu, ale to proteza
auto const lightstate { std::abs( mover->Im ) > 10.0 };
btLampkaPoslizg.Turn( btLampkaPoslizg.GetValue() || lightstate );
}
}
btLampkaSprezarkaB.Turn( mover->CompressorFlag ); // mutopsitka dziala btLampkaSprezarkaB.Turn( mover->CompressorFlag ); // mutopsitka dziala
btLampkaSprezarkaBOff.Turn( false == mover->CompressorFlag ); btLampkaSprezarkaBOff.Turn( false == mover->CompressorFlag );
@@ -6931,11 +6889,11 @@ bool TTrain::Update( double const Deltatime )
// lights // lights
auto const lightpower { ( auto const lightpower { (
InstrumentLightType == 0 ? mvControlled->Battery || mvControlled->ConverterFlag : InstrumentLightType == 0 ? mvOccupied->Power24vIsAvailable || mvOccupied->Power110vIsAvailable :
InstrumentLightType == 1 ? mvControlled->Mains : InstrumentLightType == 1 ? mvControlled->Mains :
InstrumentLightType == 2 ? mvControlled->ConverterFlag : InstrumentLightType == 2 ? mvOccupied->Power110vIsAvailable :
InstrumentLightType == 3 ? mvControlled->Battery || mvControlled->ConverterFlag : InstrumentLightType == 3 ? mvOccupied->Power24vIsAvailable || mvOccupied->Power110vIsAvailable :
InstrumentLightType == 4 ? mvControlled->Battery || mvControlled->ConverterFlag : InstrumentLightType == 4 ? mvOccupied->Power24vIsAvailable || mvOccupied->Power110vIsAvailable :
false ) }; false ) };
InstrumentLightActive = ( InstrumentLightActive = (
InstrumentLightType == 3 ? true : // TODO: link the light state with the state of the master key InstrumentLightType == 3 ? true : // TODO: link the light state with the state of the master key
@@ -7058,10 +7016,6 @@ bool TTrain::Update( double const Deltatime )
// calculate current level of interior illumination // calculate current level of interior illumination
{ {
// TODO: organize it along with rest of train update in a more sensible arrangement // TODO: organize it along with rest of train update in a more sensible arrangement
auto const converteractive{ (
( mvOccupied->ConverterFlag )
|| ( ( ( mvOccupied->Couplers[ end::front ].CouplingFlag & coupling::permanent ) != 0 ) && mvOccupied->Couplers[ end::front ].Connected->ConverterFlag )
|| ( ( ( mvOccupied->Couplers[ end::rear ].CouplingFlag & coupling::permanent ) != 0 ) && mvOccupied->Couplers[ end::rear ].Connected->ConverterFlag ) ) };
// Ra: uzeleżnic od napięcia w obwodzie sterowania // Ra: uzeleżnic od napięcia w obwodzie sterowania
// hunter-091012: uzaleznienie jasnosci od przetwornicy // hunter-091012: uzaleznienie jasnosci od przetwornicy
int cabidx { 0 }; int cabidx { 0 };
@@ -7071,7 +7025,7 @@ bool TTrain::Update( double const Deltatime )
( ( cab.bLight == false ) ? 0.f : ( ( cab.bLight == false ) ? 0.f :
( cab.bLightDim == true ) ? 0.4f : ( cab.bLightDim == true ) ? 0.4f :
1.f ) 1.f )
* ( converteractive ? 1.f : 0.5f ); * ( mvOccupied->Power110vIsAvailable ? 1.f : 0.5f );
if( cab.LightLevel != cablightlevel ) { if( cab.LightLevel != cablightlevel ) {
cab.LightLevel = cablightlevel; cab.LightLevel = cablightlevel;
@@ -7300,37 +7254,6 @@ TTrain::update_sounds( double const Deltatime ) {
rsHuntingNoise.stop( true == FreeFlyModeFlag ); rsHuntingNoise.stop( true == FreeFlyModeFlag );
} }
// McZapkie-141102: SHP i czuwak, TODO: sygnalizacja kabinowa
if (mvOccupied->SecuritySystem.Status != s_off ) {
// hunter-091012: rozdzielenie alarmow
if( TestFlag( mvOccupied->SecuritySystem.Status, s_CAalarm )
|| TestFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ) ) {
if( false == dsbBuzzer.is_playing() ) {
dsbBuzzer
.pitch( dsbBuzzer.m_frequencyoffset + dsbBuzzer.m_frequencyfactor )
.gain( dsbBuzzer.m_amplitudeoffset + dsbBuzzer.m_amplitudefactor )
.play( sound_flags::looping );
Console::BitsSet( 1 << 14 ); // ustawienie bitu 16 na PoKeys
}
}
else {
if( true == dsbBuzzer.is_playing() ) {
dsbBuzzer.stop();
Console::BitsClear( 1 << 14 ); // ustawienie bitu 16 na PoKeys
}
}
}
else {
// wylaczone
if( true == dsbBuzzer.is_playing() ) {
dsbBuzzer.stop();
Console::BitsClear( 1 << 14 ); // ustawienie bitu 16 na PoKeys
}
}
update_sounds_radio();
if( fTachoCount >= 3.f ) { if( fTachoCount >= 3.f ) {
auto const frequency { ( auto const frequency { (
true == dsbHasler.is_combined() ? true == dsbHasler.is_combined() ?
@@ -7346,7 +7269,28 @@ TTrain::update_sounds( double const Deltatime ) {
} }
// power-reliant sounds // power-reliant sounds
if( mvControlled->Battery || mvControlled->ConverterFlag ) { if( mvOccupied->Power24vIsAvailable || mvOccupied->Power110vIsAvailable ) {
// McZapkie-141102: SHP i czuwak, TODO: sygnalizacja kabinowa
if( mvOccupied->SecuritySystem.Status != s_off ) {
// hunter-091012: rozdzielenie alarmow
if( TestFlag( mvOccupied->SecuritySystem.Status, s_CAalarm )
|| TestFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ) ) {
if( false == dsbBuzzer.is_playing() ) {
dsbBuzzer
.pitch( dsbBuzzer.m_frequencyoffset + dsbBuzzer.m_frequencyfactor )
.gain( dsbBuzzer.m_amplitudeoffset + dsbBuzzer.m_amplitudefactor )
.play( sound_flags::looping );
Console::BitsSet( 1 << 14 ); // ustawienie bitu 16 na PoKeys
}
}
else {
if( true == dsbBuzzer.is_playing() ) {
dsbBuzzer.stop();
Console::BitsClear( 1 << 14 ); // ustawienie bitu 16 na PoKeys
}
}
}
// distance meter alert // distance meter alert
auto const *owner { ( auto const *owner { (
DynamicObject->ctOwner != nullptr ? DynamicObject->ctOwner != nullptr ?
@@ -7364,8 +7308,14 @@ TTrain::update_sounds( double const Deltatime ) {
} }
else { else {
// stop power-reliant sounds if power is cut // stop power-reliant sounds if power is cut
if( true == dsbBuzzer.is_playing() ) {
dsbBuzzer.stop();
Console::BitsClear( 1 << 14 ); // ustawienie bitu 16 na PoKeys
}
m_distancecounterclear.stop(); m_distancecounterclear.stop();
} }
update_sounds_radio();
} }
void TTrain::update_sounds_runningnoise( sound_source &Sound ) { void TTrain::update_sounds_runningnoise( sound_source &Sound ) {
@@ -7434,7 +7384,7 @@ void TTrain::update_sounds_radio() {
std::end( m_radiomessages ) ); std::end( m_radiomessages ) );
} }
// adjust audibility of remaining messages based on current radio conditions // adjust audibility of remaining messages based on current radio conditions
auto const radioenabled { ( true == mvOccupied->Radio ) && ( mvControlled->Battery || mvControlled->ConverterFlag ) }; auto const radioenabled { ( true == mvOccupied->Radio ) && ( mvOccupied->Power24vIsAvailable || mvOccupied->Power110vIsAvailable ) };
for( auto &message : m_radiomessages ) { for( auto &message : m_radiomessages ) {
auto const volume { auto const volume {
( true == radioenabled ) ( true == radioenabled )
@@ -7455,7 +7405,7 @@ void TTrain::update_sounds_radio() {
void TTrain::add_distance( double const Distance ) { void TTrain::add_distance( double const Distance ) {
auto const meterenabled { ( true == ( m_distancecounter >= 0 ) ) && ( mvControlled->Battery || mvControlled->ConverterFlag ) }; auto const meterenabled { ( m_distancecounter >= 0 ) && ( mvOccupied->Power24vIsAvailable || mvOccupied->Power110vIsAvailable) };
if( true == meterenabled ) { m_distancecounter += Distance * Occupied()->CabOccupied; } if( true == meterenabled ) { m_distancecounter += Distance * Occupied()->CabOccupied; }
else { m_distancecounter = -1.f; } else { m_distancecounter = -1.f; }
@@ -7467,7 +7417,7 @@ bool TTrain::CabChange(int iDirection)
|| ( true == DynamicObject->Mechanik->AIControllFlag ) ) { || ( true == DynamicObject->Mechanik->AIControllFlag ) ) {
// jeśli prowadzi AI albo jest w innym członie // jeśli prowadzi AI albo jest w innym członie
// jak AI prowadzi, to nie można mu mieszać // jak AI prowadzi, to nie można mu mieszać
if (abs(DynamicObject->MoverParameters->CabOccupied + iDirection) > 1) if (std::abs(DynamicObject->MoverParameters->CabOccupied + iDirection) > 1)
return false; // ewentualna zmiana pojazdu return false; // ewentualna zmiana pojazdu
DynamicObject->MoverParameters->CabOccupied = DynamicObject->MoverParameters->CabOccupied =
DynamicObject->MoverParameters->CabOccupied + iDirection; DynamicObject->MoverParameters->CabOccupied + iDirection;
@@ -8056,7 +8006,7 @@ void TTrain::DynamicSet(TDynamicObject *d)
if( DynamicObject == nullptr ) { return; } if( DynamicObject == nullptr ) { return; }
mvControlled = DynamicObject->ControlledFind()->MoverParameters; mvControlled = DynamicObject->FindPowered()->MoverParameters;
mvSecond = NULL; // gdyby się nic nie znalazło mvSecond = NULL; // gdyby się nic nie znalazło
if (mvOccupied->Power > 1.0) // dwuczłonowe lub ukrotnienia, żeby nie szukać każdorazowo if (mvOccupied->Power > 1.0) // dwuczłonowe lub ukrotnienia, żeby nie szukać każdorazowo
if (mvOccupied->Couplers[1].Connected ? if (mvOccupied->Couplers[1].Connected ?
@@ -8077,6 +8027,15 @@ void TTrain::DynamicSet(TDynamicObject *d)
mvSecond = mvSecond =
(TMoverParameters *)mvOccupied->Couplers[0].Connected; // wskaźnik na drugiego (TMoverParameters *)mvOccupied->Couplers[0].Connected; // wskaźnik na drugiego
} }
// cache nearest unit equipped with pantographs
{
auto *lookup { DynamicObject->FindPantographCarrier() };
// HACK: set pointer to existing vehicle to avoid error checking all over the place
mvPantographUnit = (
lookup != nullptr ?
lookup->MoverParameters :
mvControlled );
}
}; };
void void
@@ -8216,7 +8175,7 @@ TTrain::radio_message( sound_source *Message, int const Channel ) {
std::make_shared<sound_source>( m_radiosound ) ); std::make_shared<sound_source>( m_radiosound ) );
// assign sound to the template and play it // assign sound to the template and play it
auto &message = *( m_radiomessages.back().second.get() ); auto &message = *( m_radiomessages.back().second.get() );
auto const radioenabled { ( true == mvOccupied->Radio ) && ( mvControlled->Battery || mvControlled->ConverterFlag ) }; auto const radioenabled { ( true == mvOccupied->Radio ) && ( mvOccupied->Power24vIsAvailable || mvOccupied->Power110vIsAvailable ) };
auto const volume { auto const volume {
( true == radioenabled ) ( true == radioenabled )
&& ( Channel == RadioChannel() ) ? && ( Channel == RadioChannel() ) ?
@@ -8569,7 +8528,7 @@ void TTrain::set_cab_controls( int const Cab ) {
} }
if( ggPantSelectedButton.type() == TGaugeType::toggle ) { if( ggPantSelectedButton.type() == TGaugeType::toggle ) {
ggPantSelectedButton.PutValue( ggPantSelectedButton.PutValue(
( mvControlled->PantsValve.is_enabled ? ( mvPantographUnit->PantsValve.is_enabled ?
1.f : 1.f :
0.f ) ); 0.f ) );
} }
@@ -8581,7 +8540,7 @@ void TTrain::set_cab_controls( int const Cab ) {
} }
if( ggPantSelectedDownButton.type() == TGaugeType::toggle ) { if( ggPantSelectedDownButton.type() == TGaugeType::toggle ) {
ggPantSelectedDownButton.PutValue( ggPantSelectedDownButton.PutValue(
( mvControlled->PantsValve.is_disabled ? ( mvPantographUnit->PantsValve.is_disabled ?
1.f : 1.f :
0.f ) ); 0.f ) );
} }
@@ -8591,7 +8550,7 @@ void TTrain::set_cab_controls( int const Cab ) {
0.f : // default setting is pantographs connected with primary tank 0.f : // default setting is pantographs connected with primary tank
1.f ); 1.f );
ggPantCompressorButton.PutValue( ggPantCompressorButton.PutValue(
mvControlled->PantCompFlag ? mvPantographUnit->PantCompFlag ?
1.f : 1.f :
0.f ); 0.f );
// converter // converter
@@ -8934,7 +8893,7 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
{ "i-doorpermit_right:", &mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::right : side::left ) ].open_permit }, { "i-doorpermit_right:", &mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::right : side::left ) ].open_permit },
{ "i-doorstep:", &mvOccupied->Doors.step_enabled }, { "i-doorstep:", &mvOccupied->Doors.step_enabled },
{ "i-mainpipelock:", &mvOccupied->LockPipe }, { "i-mainpipelock:", &mvOccupied->LockPipe },
{ "i-battery:", &mvOccupied->Battery }, { "i-battery:", &mvOccupied->Power24vIsAvailable },
{ "i-cablight:", &Cabine[ iCabn ].bLight }, { "i-cablight:", &Cabine[ iCabn ].bLight },
}; };
{ {
@@ -9155,10 +9114,10 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
{ "doormode_sw:", &mvOccupied->Doors.remote_only }, { "doormode_sw:", &mvOccupied->Doors.remote_only },
{ "doorstep_sw:", &mvOccupied->Doors.step_enabled }, { "doorstep_sw:", &mvOccupied->Doors.step_enabled },
{ "coolingfans_sw:", &mvControlled->RVentForceOn }, { "coolingfans_sw:", &mvControlled->RVentForceOn },
{ "pantfront_sw:", &mvControlled->Pantographs[end::front].valve.is_enabled }, { "pantfront_sw:", &mvPantographUnit->Pantographs[end::front].valve.is_enabled },
{ "pantrear_sw:", &mvControlled->Pantographs[end::rear].valve.is_enabled }, { "pantrear_sw:", &mvPantographUnit->Pantographs[end::rear].valve.is_enabled },
{ "pantfrontoff_sw:", &mvControlled->Pantographs[end::front].valve.is_disabled }, { "pantfrontoff_sw:", &mvPantographUnit->Pantographs[end::front].valve.is_disabled },
{ "pantrearoff_sw:", &mvControlled->Pantographs[end::rear].valve.is_disabled }, { "pantrearoff_sw:", &mvPantographUnit->Pantographs[end::rear].valve.is_disabled },
{ "radio_sw:", &mvOccupied->Radio }, { "radio_sw:", &mvOccupied->Radio },
{ "cablight_sw:", &Cabine[ iCabn ].bLight }, { "cablight_sw:", &Cabine[ iCabn ].bLight },
{ "springbraketoggle_bt:", &mvOccupied->SpringBrake.Activate }, { "springbraketoggle_bt:", &mvOccupied->SpringBrake.Activate },
@@ -9307,7 +9266,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
// manometr zbiornika kontrolnego/rorz�du // manometr zbiornika kontrolnego/rorz�du
auto &gauge = Cabine[Cabindex].Gauge(-1); // pierwsza wolna gałka auto &gauge = Cabine[Cabindex].Gauge(-1); // pierwsza wolna gałka
gauge.Load(Parser, DynamicObject, 0.1); gauge.Load(Parser, DynamicObject, 0.1);
gauge.AssignDouble(&mvControlled->PantPress); gauge.AssignDouble(&mvPantographUnit->PantPress);
} }
else if (Label == "springbrakepress:") else if (Label == "springbrakepress:")
{ {
@@ -9351,7 +9310,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
// pantograph tank pressure // pantograph tank pressure
auto &gauge = Cabine[ Cabindex ].Gauge( -1 ); // pierwsza wolna gałka auto &gauge = Cabine[ Cabindex ].Gauge( -1 ); // pierwsza wolna gałka
gauge.Load( Parser, DynamicObject, 0.1 ); gauge.Load( Parser, DynamicObject, 0.1 );
gauge.AssignDouble( &mvOccupied->PantPress ); gauge.AssignDouble( &mvPantographUnit->PantPress );
} }
// yB - dla drugiej sekcji // yB - dla drugiej sekcji
else if (Label == "hvbcurrent1:") else if (Label == "hvbcurrent1:")

View File

@@ -432,6 +432,7 @@ class TTrain {
TMoverParameters *mvOccupied { nullptr }; // człon, w którym sterujemy hamulcem TMoverParameters *mvOccupied { nullptr }; // człon, w którym sterujemy hamulcem
TMoverParameters *mvSecond { nullptr }; // drugi człon (ET40, ET41, ET42, ukrotnienia) TMoverParameters *mvSecond { nullptr }; // drugi człon (ET40, ET41, ET42, ukrotnienia)
TMoverParameters *mvThird { nullptr }; // trzeci człon (SN61) TMoverParameters *mvThird { nullptr }; // trzeci człon (SN61)
TMoverParameters *mvPantographUnit { nullptr }; // nearest pantograph equipped unit
// helper variable, to prevent immediate switch between closing and opening line breaker circuit // helper variable, to prevent immediate switch between closing and opening line breaker circuit
int m_linebreakerstate { 0 }; // 0: open, 1: closed, 2: freshly closed (and yes this is awful way to go about it) int m_linebreakerstate { 0 }; // 0: open, 1: closed, 2: freshly closed (and yes this is awful way to go about it)
static const commandhandler_map m_commandhandlers; static const commandhandler_map m_commandhandlers;

View File

@@ -676,22 +676,29 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
( mover.FuseFlag ? '!' : '.' ), ( mover.FuseFlag ? '!' : '.' ),
( false == mover.ConverterAllowLocal ? '-' : ( mover.ConverterAllow ? ( mover.ConverterFlag ? 'X' : 'x' ) : '.' ) ), ( false == mover.ConverterAllowLocal ? '-' : ( mover.ConverterAllow ? ( mover.ConverterFlag ? 'X' : 'x' ) : '.' ) ),
( 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 && mover.CompressorSpeed > 0.0 ) ) ? 'c' : '.' ) ) ),
( mover.CompressorGovernorLock ? '!' : '.' ), ( mover.CompressorGovernorLock ? '!' : '.' ),
( mover.StLinSwitchOff ? '-' : ( mover.ControlPressureSwitch ? '!' : ( mover.StLinFlag ? '+' : '.' ) ) ), ( mover.StLinSwitchOff ? '-' : ( mover.ControlPressureSwitch ? '!' : ( mover.StLinFlag ? '+' : '.' ) ) ),
( mover.Heating ? 'H' : ( mover.HeatingAllow ? 'h' : '.' ) ), ( 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
// 3000v
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.is_local ? ":" : ":=" ).c_str(), std::string( mover.Couplers[ end::front ].power_high.is_local ? ":" : ":=" ).c_str(),
std::string( vehicle.DirectionGet() ? "<<" : ">>" ).c_str(),
mover.EngineVoltage, mover.EngineVoltage,
std::string( vehicle.DirectionGet() ? "<<" : ">>" ).c_str(),
std::string( mover.Couplers[ end::rear ].power_high.is_local ? ":" : "=:" ).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,
// 110v
mover.Couplers[ end::front ].power_110v.voltage,
mover.Couplers[ end::front ].power_110v.current,
std::string( mover.Couplers[ end::front ].power_110v.is_local ? ":" : ":=" ).c_str(),
mover.PowerCircuits[ 1 ].first,
std::string( mover.Couplers[ end::rear ].power_110v.is_local ? ":" : "=:" ).c_str(),
mover.Couplers[ end::rear ].power_110v.voltage,
mover.Couplers[ end::rear ].power_110v.current );
Output.emplace_back( m_buffer.data(), Global.UITextColor ); Output.emplace_back( m_buffer.data(), Global.UITextColor );

View File

@@ -57,8 +57,8 @@ light_array::update() {
light.direction.z = -light.direction.z; light.direction.z = -light.direction.z;
} }
// determine intensity of this light set // determine intensity of this light set
if( ( true == light.owner->MoverParameters->Battery ) if( ( true == light.owner->MoverParameters->Power24vIsAvailable )
|| ( true == light.owner->MoverParameters->ConverterFlag ) ) { || ( true == light.owner->MoverParameters->Power110vIsAvailable ) ) {
// with power on, the intensity depends on the state of activated switches // with power on, the intensity depends on the state of activated switches
// first we cross-check the list of enabled lights with the lights installed in the vehicle... // first we cross-check the list of enabled lights with the lights installed in the vehicle...
auto const lights { light.owner->iLights[ light.index ] & light.owner->LightList( static_cast<end>( light.index ) ) }; auto const lights { light.owner->iLights[ light.index ] & light.owner->LightList( static_cast<end>( light.index ) ) };

View File

@@ -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%c%c%c%s%s\nPower transfers: %.0f@%.0f%s%s[%.0f]%s%s%.0f@%.0f", "Devices: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%s%s\nPower transfers: %.0f@%.0f%s[%.0f]%s%.0f@%.0f :: %.0f@%.0f%s[%.0f]%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",
@@ -271,7 +271,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%c%c%c%s%s\nTransfer pradow: %.0f@%.0f%s%s[%.0f]%s%s%.0f@%.0f", "Urzadzenia: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%s%s\nTransfer pradow: %.0f@%.0f%s[%.0f]%s%.0f@%.0f :: %.0f@%.0f%s[%.0f]%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",