mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 19:09:18 +02:00
Merge branch 'tmj-dev' into milek-dev
This commit is contained in:
299
Driver.cpp
299
Driver.cpp
@@ -454,7 +454,7 @@ bool TController::TableAddNew()
|
|||||||
return true; // false gdy się nałoży
|
return true; // false gdy się nałoży
|
||||||
};
|
};
|
||||||
|
|
||||||
bool TController::TableNotFound(basic_event const *Event) const
|
bool TController::TableNotFound(basic_event const *Event, double const Distance ) const
|
||||||
{ // sprawdzenie, czy nie został już dodany do tabelki (np. podwójne W4 robi problemy)
|
{ // sprawdzenie, czy nie został już dodany do tabelki (np. podwójne W4 robi problemy)
|
||||||
auto lookup =
|
auto lookup =
|
||||||
std::find_if(
|
std::find_if(
|
||||||
@@ -469,7 +469,11 @@ bool TController::TableNotFound(basic_event const *Event) const
|
|||||||
WriteLog( "Speed table for " + OwnerName() + " already contains event " + lookup->evEvent->m_name );
|
WriteLog( "Speed table for " + OwnerName() + " already contains event " + lookup->evEvent->m_name );
|
||||||
}
|
}
|
||||||
|
|
||||||
return lookup == sSpeedTable.end();
|
// ignore duplicates which seem to be reasonably apart from each other, on account of looping tracks
|
||||||
|
// NOTE: since supplied distance is only rough approximation of distance to the event, we're using large safety margin
|
||||||
|
return (
|
||||||
|
( lookup == sSpeedTable.end() )
|
||||||
|
|| ( Distance - lookup->fDist > 100.0 ) );
|
||||||
};
|
};
|
||||||
|
|
||||||
void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
||||||
@@ -573,7 +577,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
|||||||
for( auto *pEvent : events ) {
|
for( auto *pEvent : events ) {
|
||||||
if( pEvent != nullptr ) // jeśli jest semafor na tym torze
|
if( pEvent != nullptr ) // jeśli jest semafor na tym torze
|
||||||
{ // trzeba sprawdzić tabelkę, bo dodawanie drugi raz tego samego przystanku nie jest korzystne
|
{ // trzeba sprawdzić tabelkę, bo dodawanie drugi raz tego samego przystanku nie jest korzystne
|
||||||
if (TableNotFound(pEvent)) // jeśli nie ma
|
if (TableNotFound(pEvent, fCurrentDistance)) // jeśli nie ma
|
||||||
{
|
{
|
||||||
TableAddNew(); // zawsze jest true
|
TableAddNew(); // zawsze jest true
|
||||||
|
|
||||||
@@ -1018,7 +1022,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
|
|
||||||
if (TrainParams->StationIndex < TrainParams->StationCount) {
|
if (TrainParams->StationIndex < TrainParams->StationCount) {
|
||||||
// jeśli są dalsze stacje, czekamy do godziny odjazdu
|
// jeśli są dalsze stacje, czekamy do godziny odjazdu
|
||||||
if (TrainParams->IsTimeToGo(simulation::Time.data().wHour, simulation::Time.data().wMinute)) {
|
if (TrainParams->IsTimeToGo(simulation::Time.data().wHour, simulation::Time.data().wMinute + simulation::Time.data().wSecond*0.0167 )) {
|
||||||
// z dalszą akcją czekamy do godziny odjazdu
|
// z dalszą akcją czekamy do godziny odjazdu
|
||||||
IsAtPassengerStop = false;
|
IsAtPassengerStop = false;
|
||||||
// przy jakim dystansie (stanie licznika) ma przesunąć na następny postój
|
// przy jakim dystansie (stanie licznika) ma przesunąć na następny postój
|
||||||
@@ -1470,7 +1474,8 @@ TController::braking_distance_multiplier( float const Targetvelocity ) const {
|
|||||||
if( ( mvOccupied->TrainType == dt_DMU )
|
if( ( mvOccupied->TrainType == dt_DMU )
|
||||||
&& ( mvOccupied->Vel < 40.0 )
|
&& ( mvOccupied->Vel < 40.0 )
|
||||||
&& ( Targetvelocity == 0.f ) ) {
|
&& ( Targetvelocity == 0.f ) ) {
|
||||||
return interpolate( 2.f, 1.f, static_cast<float>( mvOccupied->Vel / 40.0 ) );
|
auto const multiplier { clamp( 1.f + iVehicles * 0.5f, 2.f, 4.f ) };
|
||||||
|
return interpolate( multiplier, 1.f, static_cast<float>( mvOccupied->Vel / 40.0 ) );
|
||||||
}
|
}
|
||||||
// HACK: cargo trains or trains going downhill with high braking threshold need more distance to come to a full stop
|
// HACK: cargo trains or trains going downhill with high braking threshold need more distance to come to a full stop
|
||||||
if( ( fBrake_a0[ 1 ] > 0.2 )
|
if( ( fBrake_a0[ 1 ] > 0.2 )
|
||||||
@@ -2008,7 +2013,7 @@ void TController::AutoRewident()
|
|||||||
fBrakeReaction = 0.25;
|
fBrakeReaction = 0.25;
|
||||||
}
|
}
|
||||||
else if( mvOccupied->TrainType == dt_DMU ) {
|
else if( mvOccupied->TrainType == dt_DMU ) {
|
||||||
fNominalAccThreshold = std::max( -0.45, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
|
fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
|
||||||
fBrakeReaction = 0.25;
|
fBrakeReaction = 0.25;
|
||||||
}
|
}
|
||||||
else if (ustaw > 16) {
|
else if (ustaw > 16) {
|
||||||
@@ -2120,11 +2125,12 @@ bool TController::CheckVehicles(TOrders user)
|
|||||||
while (p)
|
while (p)
|
||||||
{
|
{
|
||||||
// HACK: wagony muszą mieć baterię załączoną do otwarcia drzwi...
|
// HACK: wagony muszą mieć baterię załączoną do otwarcia drzwi...
|
||||||
if( ( p != pVehicle )
|
if( p != pVehicle ) {
|
||||||
&& ( ( p->MoverParameters->Couplers[ end::front ].CouplingFlag & ( coupling::control ) ) == 0 )
|
if( ( ( p->MoverParameters->Couplers[ end::front ].CouplingFlag & ( coupling::control ) ) == 0 )
|
||||||
&& ( ( p->MoverParameters->Couplers[ end::rear ].CouplingFlag & ( coupling::control ) ) == 0 ) ) {
|
&& ( ( p->MoverParameters->Couplers[ end::rear ].CouplingFlag & ( coupling::control ) ) == 0 ) ) {
|
||||||
// NOTE: don't set battery in the occupied vehicle, let the user/ai do it explicitly
|
// NOTE: don't set battery in the occupied vehicle, let the user/ai do it explicitly
|
||||||
p->MoverParameters->BatterySwitch( true );
|
p->MoverParameters->BatterySwitch( true );
|
||||||
|
}
|
||||||
// enable heating and converter in carriages with can be heated
|
// enable heating and converter in carriages with can be heated
|
||||||
if( p->MoverParameters->HeatingPower > 0 ) {
|
if( p->MoverParameters->HeatingPower > 0 ) {
|
||||||
p->MoverParameters->HeatingAllow = true;
|
p->MoverParameters->HeatingAllow = true;
|
||||||
@@ -2366,6 +2372,10 @@ double TController::BrakeAccFactor() const
|
|||||||
|| ( mvOccupied->Vel > VelDesired + fVelPlus ) ) ) {
|
|| ( mvOccupied->Vel > VelDesired + fVelPlus ) ) ) {
|
||||||
Factor += ( fBrakeReaction * ( /*mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition < 0.5 ? 1.5 : 1 ) ) * mvOccupied->Vel / ( std::max( 0.0, ActualProximityDist ) + 1 ) * ( ( AccDesired - AbsAccS_pub ) / fAccThreshold );
|
Factor += ( fBrakeReaction * ( /*mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition < 0.5 ? 1.5 : 1 ) ) * mvOccupied->Vel / ( std::max( 0.0, ActualProximityDist ) + 1 ) * ( ( AccDesired - AbsAccS_pub ) / fAccThreshold );
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
if (mvOccupied->TrainType == dt_DMU && mvOccupied->Vel > 40 && VelNext<40)
|
||||||
|
Factor *= 1 + 0.25 * ( (1600 - VelNext * VelNext) / (mvOccupied->Vel * mvOccupied->Vel) );
|
||||||
|
*/
|
||||||
return Factor;
|
return Factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2719,8 +2729,12 @@ bool TController::IncBrake()
|
|||||||
// NOTE: we could simplify this by doing only check of the rear coupler, but this can be quite tricky in itself
|
// NOTE: we could simplify this by doing only check of the rear coupler, but this can be quite tricky in itself
|
||||||
// TODO: add easier ways to access front/rear coupler taking into account vehicle's direction
|
// TODO: add easier ways to access front/rear coupler taking into account vehicle's direction
|
||||||
standalone =
|
standalone =
|
||||||
( ( ( vehicle->MoverParameters->Couplers[ end::front ].Connected == nullptr ) || ( vehicle->MoverParameters->Couplers[ end::front ].CouplingFlag & coupling::control ) )
|
( ( ( vehicle->MoverParameters->Couplers[ end::front ].Connected == nullptr )
|
||||||
&& ( ( vehicle->MoverParameters->Couplers[ end::rear ].Connected == nullptr ) || ( vehicle->MoverParameters->Couplers[ end::rear ].CouplingFlag & coupling::control ) ) );
|
|| ( ( vehicle->MoverParameters->Couplers[ end::front ].CouplingFlag & coupling::control )
|
||||||
|
&& ( vehicle->MoverParameters->Couplers[ end::front ].Connected->Power > 1 ) ) )
|
||||||
|
&& ( ( vehicle->MoverParameters->Couplers[ end::rear ].Connected == nullptr )
|
||||||
|
|| ( ( vehicle->MoverParameters->Couplers[ end::rear ].CouplingFlag & coupling::control )
|
||||||
|
&& ( vehicle->MoverParameters->Couplers[ end::rear ].Connected->Power > 1 ) ) ) );
|
||||||
vehicle = vehicle->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła)
|
vehicle = vehicle->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2770,17 +2784,15 @@ bool TController::IncBrake()
|
|||||||
{
|
{
|
||||||
if( /*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition < 0.1 ) {
|
if( /*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition < 0.1 ) {
|
||||||
OK = /*mvOccupied->*/BrakeLevelAdd( BrakingInitialLevel ); //GBH
|
OK = /*mvOccupied->*/BrakeLevelAdd( BrakingInitialLevel ); //GBH
|
||||||
/*
|
|
||||||
// HACK: stronger braking to overcome SA134 engine behaviour
|
// HACK: stronger braking to overcome SA134 engine behaviour
|
||||||
if( ( mvOccupied->TrainType == dt_DMU )
|
if( ( mvOccupied->TrainType == dt_DMU )
|
||||||
&& ( VelNext == 0.0 )
|
&& ( VelNext == 0.0 )
|
||||||
&& ( fBrakeDist < 200.0 ) ) {
|
&& ( fBrakeDist < 200.0 ) ) {
|
||||||
mvOccupied->BrakeLevelAdd(
|
BrakeLevelAdd(
|
||||||
fBrakeDist / ActualProximityDist < 0.8 ?
|
fBrakeDist / ActualProximityDist < 0.8 ?
|
||||||
1.0 :
|
0.5 :
|
||||||
3.0 );
|
1.0 );
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2801,7 +2813,9 @@ bool TController::IncBrake()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition > 0 ) {
|
if( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition > 0 ) {
|
||||||
mvOccupied->BrakeReleaser( 0 );
|
if( mvOccupied->Hamulec->Releaser() ) {
|
||||||
|
mvOccupied->BrakeReleaser( 0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2833,20 +2847,20 @@ bool TController::IncBrake()
|
|||||||
bool TController::IncBrakeEIM()
|
bool TController::IncBrakeEIM()
|
||||||
{ // zwiększenie hamowania
|
{ // zwiększenie hamowania
|
||||||
bool OK = false;
|
bool OK = false;
|
||||||
switch (mvControlling->EIMCtrlType)
|
switch (mvOccupied->EIMCtrlType)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
OK = mvControlling->IncLocalBrakeLevel(1);
|
OK = mvOccupied->IncLocalBrakeLevel(1);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
OK = mvControlling->MainCtrlPos > 0;
|
OK = mvOccupied->MainCtrlPos > 0;
|
||||||
if (OK)
|
if (OK)
|
||||||
mvControlling->MainCtrlPos = 0;
|
mvOccupied->MainCtrlPos = 0;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
OK = mvControlling->MainCtrlPos > 1;
|
OK = mvOccupied->MainCtrlPos > 1;
|
||||||
if (OK)
|
if (OK)
|
||||||
mvControlling->MainCtrlPos = 1;
|
mvOccupied->MainCtrlPos = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
@@ -2855,7 +2869,8 @@ bool TController::IncBrakeEIM()
|
|||||||
bool TController::DecBrake()
|
bool TController::DecBrake()
|
||||||
{ // zmniejszenie siły hamowania
|
{ // zmniejszenie siły hamowania
|
||||||
bool OK = false;
|
bool OK = false;
|
||||||
double deltaAcc = 0;
|
double deltaAcc = -1.0;
|
||||||
|
double pos_diff = 1.0;
|
||||||
switch (mvOccupied->BrakeSystem)
|
switch (mvOccupied->BrakeSystem)
|
||||||
{
|
{
|
||||||
case TBrakeSystem::Individual:
|
case TBrakeSystem::Individual:
|
||||||
@@ -2865,7 +2880,12 @@ bool TController::DecBrake()
|
|||||||
OK = mvOccupied->DecLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired)));
|
OK = mvOccupied->DecLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired)));
|
||||||
break;
|
break;
|
||||||
case TBrakeSystem::Pneumatic:
|
case TBrakeSystem::Pneumatic:
|
||||||
deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition -1.0)*fBrake_a1[0]);
|
if( ( fBrake_a0[ 0 ] != 0.0 )
|
||||||
|
|| ( fBrake_a1[ 0 ] != 0.0 ) ) {
|
||||||
|
if( mvOccupied->TrainType == dt_DMU )
|
||||||
|
pos_diff = 0.25;
|
||||||
|
deltaAcc = -AccDesired*BrakeAccFactor() - (fBrake_a0[0] + 4 * (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition - pos_diff)*fBrake_a1[0]);
|
||||||
|
}
|
||||||
if (deltaAcc < 0)
|
if (deltaAcc < 0)
|
||||||
{
|
{
|
||||||
if (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition > 0)
|
if (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition > 0)
|
||||||
@@ -2884,8 +2904,11 @@ bool TController::DecBrake()
|
|||||||
if (!OK) {
|
if (!OK) {
|
||||||
OK = DecBrakeEIM();
|
OK = DecBrakeEIM();
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
// NOTE: disabled, duplicate of AI's behaviour in UpdateSituation()
|
||||||
if (mvOccupied->PipePress < 3.0)
|
if (mvOccupied->PipePress < 3.0)
|
||||||
Need_BrakeRelease = true;
|
Need_BrakeRelease = true;
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
case TBrakeSystem::ElectroPneumatic:
|
case TBrakeSystem::ElectroPneumatic:
|
||||||
if (mvOccupied->EngineType == TEngineType::ElectricInductionMotor) {
|
if (mvOccupied->EngineType == TEngineType::ElectricInductionMotor) {
|
||||||
@@ -2916,20 +2939,20 @@ bool TController::DecBrake()
|
|||||||
bool TController::DecBrakeEIM()
|
bool TController::DecBrakeEIM()
|
||||||
{ // zmniejszenie siły hamowania
|
{ // zmniejszenie siły hamowania
|
||||||
bool OK = false;
|
bool OK = false;
|
||||||
switch (mvControlling->EIMCtrlType)
|
switch (mvOccupied->EIMCtrlType)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
OK = mvControlling->DecLocalBrakeLevel(1);
|
OK = mvOccupied->DecLocalBrakeLevel(1);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
OK = mvControlling->MainCtrlPos < 2;
|
OK = mvOccupied->MainCtrlPos < 2;
|
||||||
if (OK)
|
if (OK)
|
||||||
mvControlling->MainCtrlPos = 2;
|
mvOccupied->MainCtrlPos = 2;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
OK = mvControlling->MainCtrlPos < 3;
|
OK = mvOccupied->MainCtrlPos < 3;
|
||||||
if (OK)
|
if (OK)
|
||||||
mvControlling->MainCtrlPos = 3;
|
mvOccupied->MainCtrlPos = 3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
@@ -2982,6 +3005,7 @@ bool TController::IncSpeed()
|
|||||||
// if it generates enough traction force
|
// if it generates enough traction force
|
||||||
// to build up speed to 30/40 km/h for passenger/cargo train (10 km/h less if going uphill)
|
// to build up speed to 30/40 km/h for passenger/cargo train (10 km/h less if going uphill)
|
||||||
auto const sufficienttractionforce { std::abs( mvControlling->Ft ) > ( IsHeavyCargoTrain ? 125 : 100 ) * 1000.0 };
|
auto const sufficienttractionforce { std::abs( mvControlling->Ft ) > ( IsHeavyCargoTrain ? 125 : 100 ) * 1000.0 };
|
||||||
|
auto const sufficientacceleration { AbsAccS_pub >= ( IsHeavyCargoTrain ? 0.02 : 0.04 ) };
|
||||||
auto const seriesmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 ) };
|
auto const seriesmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 ) };
|
||||||
auto const parallelmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 ) };
|
auto const parallelmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 ) };
|
||||||
auto const useseriesmodevoltage {
|
auto const useseriesmodevoltage {
|
||||||
@@ -2993,6 +3017,7 @@ bool TController::IncSpeed()
|
|||||||
( mvControlling->Imax > mvControlling->ImaxLo )
|
( mvControlling->Imax > mvControlling->ImaxLo )
|
||||||
|| ( fVoltage < useseriesmodevoltage )
|
|| ( fVoltage < useseriesmodevoltage )
|
||||||
|| ( ( true == sufficienttractionforce )
|
|| ( ( true == sufficienttractionforce )
|
||||||
|
&& ( true == sufficientacceleration )
|
||||||
&& ( mvOccupied->Vel <= ( IsCargoTrain ? 35 : 25 ) + ( seriesmodefieldshunting ? 5 : 0 ) - ( ( fAccGravity < -0.025 ) ? 10 : 0 ) ) ) );
|
&& ( mvOccupied->Vel <= ( IsCargoTrain ? 35 : 25 ) + ( seriesmodefieldshunting ? 5 : 0 ) - ( ( fAccGravity < -0.025 ) ? 10 : 0 ) ) ) );
|
||||||
// when not in series mode use the first available parallel mode configuration until 50/60 km/h for passenger/cargo train
|
// when not in series mode use the first available parallel mode configuration until 50/60 km/h for passenger/cargo train
|
||||||
// (if there's only one parallel mode configuration it'll be used regardless of current speed)
|
// (if there's only one parallel mode configuration it'll be used regardless of current speed)
|
||||||
@@ -3002,6 +3027,7 @@ bool TController::IncSpeed()
|
|||||||
&& ( useseriesmode ?
|
&& ( useseriesmode ?
|
||||||
mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 :
|
mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 :
|
||||||
( ( true == sufficienttractionforce )
|
( ( true == sufficienttractionforce )
|
||||||
|
&& ( true == sufficientacceleration )
|
||||||
&& ( mvOccupied->Vel <= ( IsCargoTrain ? 55 : 45 ) + ( parallelmodefieldshunting ? 5 : 0 ) ) ?
|
&& ( mvOccupied->Vel <= ( IsCargoTrain ? 55 : 45 ) + ( parallelmodefieldshunting ? 5 : 0 ) ) ?
|
||||||
mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 :
|
mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 :
|
||||||
mvControlling->MainCtrlPos == mvControlling->MainCtrlPosNo ) ) );
|
mvControlling->MainCtrlPos == mvControlling->MainCtrlPosNo ) ) );
|
||||||
@@ -3441,6 +3467,21 @@ void TController::SetTimeControllers()
|
|||||||
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_NP));
|
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_NP));
|
||||||
}
|
}
|
||||||
if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) mvOccupied->BrakeLevelSet(BrakeCtrlPosition);
|
if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) mvOccupied->BrakeLevelSet(BrakeCtrlPosition);
|
||||||
|
if (mvOccupied->BrakeHandle == TBrakeHandle::MHZ_K8P)
|
||||||
|
{
|
||||||
|
if (BrakeCtrlPosition == 0)
|
||||||
|
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_RP));
|
||||||
|
else if (BrakeCtrlPosition == -1)
|
||||||
|
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_FS));
|
||||||
|
else if (BrakeCtrlPosition == -2)
|
||||||
|
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_NP));
|
||||||
|
else if (BrakeCtrlPosition > 4.5)
|
||||||
|
mvOccupied->BrakeLevelSet(10);
|
||||||
|
else if (BrakeCtrlPosition > 3.70)
|
||||||
|
mvOccupied->BrakeLevelSet(9);
|
||||||
|
else
|
||||||
|
mvOccupied->BrakeLevelSet(round((BrakeCtrlPosition * 0.4 - 0.1) / 0.15));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//2. Check the type of Secondary Brake Handle
|
//2. Check the type of Secondary Brake Handle
|
||||||
|
|
||||||
@@ -3472,6 +3513,26 @@ void TController::SetTimeControllers()
|
|||||||
mvOccupied->ScndCtrlPos = 1;
|
mvOccupied->ScndCtrlPos = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//5. Check Main Controller in Dizels
|
||||||
|
if ((mvControlling->EngineType == TEngineType::DieselEngine)&&(mvControlling->Vmax>30))
|
||||||
|
{
|
||||||
|
int MaxPos = mvControlling->MainCtrlPosNo;
|
||||||
|
int MinPos = MaxPos;
|
||||||
|
for (int i = MaxPos; (i > 1) && (mvControlling->RList[i].Mn > 0); i--) MinPos = i;
|
||||||
|
if ((MaxPos > MinPos)&&(mvControlling->MainCtrlPos>0)&&(AccDesired>0))
|
||||||
|
{
|
||||||
|
double Factor = 5 * (mvControlling->Vmax) / (mvControlling->Vmax + mvControlling->Vel);
|
||||||
|
int DesiredPos = MinPos + (MaxPos - MinPos)*(VelDesired > mvControlling->Vel ? (VelDesired - mvControlling->Vel) / Factor : 0);
|
||||||
|
if (DesiredPos > MaxPos) DesiredPos = MaxPos;
|
||||||
|
if (DesiredPos < MinPos) DesiredPos = MinPos;
|
||||||
|
if (!mvControlling->SlippingWheels)
|
||||||
|
{
|
||||||
|
while (mvControlling->MainCtrlPos > DesiredPos) mvControlling->DecMainCtrl(1);
|
||||||
|
if (mvControlling->Vel>mvControlling->dizel_minVelfullengage)
|
||||||
|
while (mvControlling->MainCtrlPos < DesiredPos) mvControlling->IncMainCtrl(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void TController::CheckTimeControllers()
|
void TController::CheckTimeControllers()
|
||||||
@@ -3568,13 +3629,14 @@ void TController::Doors( bool const Open, int const Side ) {
|
|||||||
|| ( false == AIControllFlag ) ) ) {
|
|| ( false == AIControllFlag ) ) ) {
|
||||||
// ai doesn't close the door until it's free to depart, but human driver has free reign to do stupid things
|
// ai doesn't close the door until it's free to depart, but human driver has free reign to do stupid things
|
||||||
if( ( pVehicle->MoverParameters->Doors.close_control == control_t::conductor )
|
if( ( pVehicle->MoverParameters->Doors.close_control == control_t::conductor )
|
||||||
|| ( ( true == AIControllFlag )
|
|| ( ( true == AIControllFlag ) ) ) {
|
||||||
&& ( ( pVehicle->MoverParameters->Doors.close_control == control_t::driver )
|
|
||||||
|| ( pVehicle->MoverParameters->Doors.close_control == control_t::mixed ) ) ) ) {
|
|
||||||
// if the door are controlled by the driver, we let the user operate them unless this user is an ai
|
// if the door are controlled by the driver, we let the user operate them unless this user is an ai
|
||||||
// the train conductor, if present, handles door operation also for human-driven trains
|
// the train conductor, if present, handles door operation also for human-driven trains
|
||||||
pVehicle->MoverParameters->OperateDoors( side::right, false );
|
if( ( pVehicle->MoverParameters->Doors.close_control == control_t::driver )
|
||||||
pVehicle->MoverParameters->OperateDoors( side::left, false );
|
|| ( pVehicle->MoverParameters->Doors.close_control == control_t::mixed ) ) {
|
||||||
|
pVehicle->MoverParameters->OperateDoors( side::right, false );
|
||||||
|
pVehicle->MoverParameters->OperateDoors( side::left, false );
|
||||||
|
}
|
||||||
if( pVehicle->MoverParameters->Doors.permit_needed ) {
|
if( pVehicle->MoverParameters->Doors.permit_needed ) {
|
||||||
pVehicle->MoverParameters->PermitDoors( side::right, false );
|
pVehicle->MoverParameters->PermitDoors( side::right, false );
|
||||||
pVehicle->MoverParameters->PermitDoors( side::left, false );
|
pVehicle->MoverParameters->PermitDoors( side::left, false );
|
||||||
@@ -4137,6 +4199,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
// HACK: activate route scanning if an idling vehicle is activated by a human user
|
// HACK: activate route scanning if an idling vehicle is activated by a human user
|
||||||
if( ( OrderCurrentGet() == Wait_for_orders )
|
if( ( OrderCurrentGet() == Wait_for_orders )
|
||||||
&& ( false == AIControllFlag )
|
&& ( false == AIControllFlag )
|
||||||
|
&& ( false == iEngineActive )
|
||||||
&& ( true == mvControlling->Battery ) ) {
|
&& ( true == mvControlling->Battery ) ) {
|
||||||
OrderNext( Prepare_engine );
|
OrderNext( Prepare_engine );
|
||||||
}
|
}
|
||||||
@@ -4965,54 +5028,50 @@ TController::UpdateSituation(double dt) {
|
|||||||
// jeśli dociskanie w celu odczepienia
|
// jeśli dociskanie w celu odczepienia
|
||||||
// 3. faza odczepiania.
|
// 3. faza odczepiania.
|
||||||
SetVelocity(2, 0); // jazda w ustawionym kierunku z prędkością 2
|
SetVelocity(2, 0); // jazda w ustawionym kierunku z prędkością 2
|
||||||
if( ( mvControlling->MainCtrlPowerPos() > 0 )
|
if( iVehicleCount >= 0 ) {
|
||||||
|| ( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) ) {
|
// zmieni się po odczepieniu
|
||||||
// jeśli jazda
|
WriteLog( mvOccupied->Name + " dociskanie..." );
|
||||||
WriteLog(mvOccupied->Name + " odczepianie w kierunku " + std::to_string(mvOccupied->DirAbsolute));
|
while( mvOccupied->DecLocalBrakeLevel( 1 ) ) { // dociśnij sklad
|
||||||
TDynamicObject *p = pVehicle; // pojazd do odczepienia, w (pVehicle) siedzi AI
|
;
|
||||||
int d; // numer sprzęgu, który sprawdzamy albo odczepiamy
|
|
||||||
int n = iVehicleCount; // ile wagonów ma zostać
|
|
||||||
do
|
|
||||||
{ // szukanie pojazdu do odczepienia
|
|
||||||
d = p->DirectionGet() > 0 ?
|
|
||||||
end::front :
|
|
||||||
end::rear; // numer sprzęgu od strony czoła składu
|
|
||||||
// if (p->MoverParameters->Couplers[d].CouplerType==Articulated)
|
|
||||||
// //jeśli sprzęg typu wózek (za mało)
|
|
||||||
if (p->MoverParameters->Couplers[d].CouplingFlag & ctrain_depot) // jeżeli sprzęg zablokowany
|
|
||||||
// if (p->GetTrack()->) //a nie stoi na torze warsztatowym
|
|
||||||
// (ustalić po czym poznać taki tor)
|
|
||||||
++n; // to liczymy człony jako jeden
|
|
||||||
p->MoverParameters->BrakeReleaser(1); // wyluzuj pojazd, aby dało się dopychać
|
|
||||||
// GBH p->MoverParameters->BrakeLevelSet(0); // hamulec na zero, aby nie hamował
|
|
||||||
BrakeLevelSet(gbh_RP);
|
|
||||||
if (n)
|
|
||||||
{ // jeśli jeszcze nie koniec
|
|
||||||
p = p->Prev(); // kolejny w stronę czoła składu (licząc od tyłu), bo dociskamy
|
|
||||||
if (!p)
|
|
||||||
iVehicleCount = -2,
|
|
||||||
n = 0; // nie ma co dalej sprawdzać, doczepianie zakończone
|
|
||||||
}
|
|
||||||
} while (n--);
|
|
||||||
if( ( p == nullptr )
|
|
||||||
|| ( p->MoverParameters->Couplers[ d ].Connected == nullptr ) ) {
|
|
||||||
// no target, or already just virtual coupling
|
|
||||||
WriteLog( mvOccupied->Name + " didn't find anything to disconnect." );
|
|
||||||
iVehicleCount = -2; // odczepiono, co było do odczepienia
|
|
||||||
} else if ( p->Dettach(d) == coupling::faux ) {
|
|
||||||
// tylko jeśli odepnie
|
|
||||||
WriteLog( mvOccupied->Name + " odczepiony." );
|
|
||||||
iVehicleCount = -2;
|
|
||||||
} // a jak nie, to dociskać dalej
|
|
||||||
}
|
|
||||||
if (iVehicleCount >= 0) // zmieni się po odczepieniu
|
|
||||||
if (!mvOccupied->DecLocalBrakeLevel(1))
|
|
||||||
{ // dociśnij sklad
|
|
||||||
WriteLog( mvOccupied->Name + " dociskanie..." );
|
|
||||||
// mvOccupied->BrakeReleaser(); //wyluzuj lokomotywę
|
|
||||||
// Ready=true; //zamiast sprawdzenia odhamowania całego składu
|
|
||||||
IncSpeed(); // dla (Ready)==false nie ruszy
|
|
||||||
}
|
}
|
||||||
|
IncSpeed();
|
||||||
|
}
|
||||||
|
WriteLog(mvOccupied->Name + " odczepianie w kierunku " + std::to_string(mvOccupied->DirAbsolute));
|
||||||
|
TDynamicObject *p = pVehicle; // pojazd do odczepienia, w (pVehicle) siedzi AI
|
||||||
|
int d; // numer sprzęgu, który sprawdzamy albo odczepiamy
|
||||||
|
int n = iVehicleCount; // ile wagonów ma zostać
|
||||||
|
do
|
||||||
|
{ // szukanie pojazdu do odczepienia
|
||||||
|
d = p->DirectionGet() > 0 ?
|
||||||
|
end::front :
|
||||||
|
end::rear; // numer sprzęgu od strony czoła składu
|
||||||
|
// if (p->MoverParameters->Couplers[d].CouplerType==Articulated)
|
||||||
|
// //jeśli sprzęg typu wózek (za mało)
|
||||||
|
if (p->MoverParameters->Couplers[d].CouplingFlag & ctrain_depot) // jeżeli sprzęg zablokowany
|
||||||
|
// if (p->GetTrack()->) //a nie stoi na torze warsztatowym
|
||||||
|
// (ustalić po czym poznać taki tor)
|
||||||
|
++n; // to liczymy człony jako jeden
|
||||||
|
p->MoverParameters->BrakeReleaser(1); // wyluzuj pojazd, aby dało się dopychać
|
||||||
|
// GBH p->MoverParameters->BrakeLevelSet(0); // hamulec na zero, aby nie hamował
|
||||||
|
BrakeLevelSet(gbh_RP);
|
||||||
|
if (n)
|
||||||
|
{ // jeśli jeszcze nie koniec
|
||||||
|
p = p->Prev(); // kolejny w stronę czoła składu (licząc od tyłu), bo dociskamy
|
||||||
|
if (!p)
|
||||||
|
iVehicleCount = -2,
|
||||||
|
n = 0; // nie ma co dalej sprawdzać, doczepianie zakończone
|
||||||
|
}
|
||||||
|
} while (n--);
|
||||||
|
if( ( p == nullptr )
|
||||||
|
|| ( p->MoverParameters->Couplers[ d ].Connected == nullptr ) ) {
|
||||||
|
// no target, or already just virtual coupling
|
||||||
|
WriteLog( mvOccupied->Name + " didn't find anything to disconnect." );
|
||||||
|
iVehicleCount = -2; // odczepiono, co było do odczepienia
|
||||||
|
} else if ( p->Dettach(d) == coupling::faux ) {
|
||||||
|
// tylko jeśli odepnie
|
||||||
|
WriteLog( mvOccupied->Name + " odczepiony." );
|
||||||
|
iVehicleCount = -2;
|
||||||
|
} // a jak nie, to dociskać dalej
|
||||||
}
|
}
|
||||||
if ((mvOccupied->Vel < 0.01) && !(iDrivigFlags & movePress))
|
if ((mvOccupied->Vel < 0.01) && !(iDrivigFlags & movePress))
|
||||||
{ // 2. faza odczepiania: zmień kierunek na przeciwny i dociśnij
|
{ // 2. faza odczepiania: zmień kierunek na przeciwny i dociśnij
|
||||||
@@ -5683,16 +5742,32 @@ TController::UpdateSituation(double dt) {
|
|||||||
ReactionTime = 0.25;
|
ReactionTime = 0.25;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic) // napełnianie uderzeniowe
|
if (mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic) {
|
||||||
if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a || mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P
|
// napełnianie uderzeniowe
|
||||||
|| mvOccupied->BrakeHandle == TBrakeHandle::M394)
|
if( ( mvOccupied->BrakeHandle == TBrakeHandle::FV4a )
|
||||||
{
|
|| ( mvOccupied->BrakeHandle == TBrakeHandle::MHZ_6P )
|
||||||
|
|| ( mvOccupied->BrakeHandle == TBrakeHandle::M394 ) ) {
|
||||||
|
|
||||||
if( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == -2 ) {
|
if( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == -2 ) {
|
||||||
/*mvOccupied->*/BrakeLevelSet( gbh_RP );
|
/*mvOccupied->*/BrakeLevelSet( gbh_RP );
|
||||||
}
|
}
|
||||||
if( ( mvOccupied->PipePress < 3.0 )
|
|
||||||
&& ( AccDesired > -0.03 ) ) {
|
// TODO: combine all releaser handling in single decision tree instead of having bits all over the place
|
||||||
mvOccupied->BrakeReleaser( 1 );
|
if( ( AccDesired > -0.03 )
|
||||||
|
&& ( false == mvOccupied->Hamulec->Releaser() ) ) {
|
||||||
|
if( mvOccupied->PipePress < 3.0 ) {
|
||||||
|
mvOccupied->BrakeReleaser( 1 );
|
||||||
|
}
|
||||||
|
if( ( mvOccupied->BrakePress > 0.4 )
|
||||||
|
&& ( mvOccupied->Hamulec->GetCRP() > 4.9 ) ) {
|
||||||
|
// wyluzuj lokomotywę, to szybciej ruszymy
|
||||||
|
mvOccupied->BrakeReleaser( 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( ( mvOccupied->PipePress > 3.0 )
|
||||||
|
&& ( mvOccupied->Hamulec->Releaser() ) ) {
|
||||||
|
// don't overcharge train brake pipe
|
||||||
|
mvOccupied->BrakeReleaser( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == 0 )
|
if( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition == 0 )
|
||||||
@@ -5700,31 +5775,37 @@ TController::UpdateSituation(double dt) {
|
|||||||
&& ( AccDesired > -0.03 )
|
&& ( AccDesired > -0.03 )
|
||||||
&& ( VelDesired - mvOccupied->Vel > 2.0 ) ) {
|
&& ( VelDesired - mvOccupied->Vel > 2.0 ) ) {
|
||||||
|
|
||||||
if( ( mvOccupied->EqvtPipePress < 4.95 )
|
if( ( mvOccupied->EqvtPipePress < 4.5 )
|
||||||
&& ( fReady > 0.35 )
|
&& ( fReady > 0.35 )
|
||||||
&& ( BrakeChargingCooldown >= 0.0 ) ) {
|
&& ( BrakeChargingCooldown >= 0.0 )
|
||||||
|
&& ( ( ActualProximityDist > 100.0 ) // don't charge if we're about to be braking soon
|
||||||
|
|| ( min_speed( mvOccupied->Vel, VelNext ) == mvOccupied->Vel ) ) ) {
|
||||||
|
|
||||||
if( ( iDrivigFlags & moveOerlikons )
|
if( ( iDrivigFlags & moveOerlikons )
|
||||||
|| ( true == IsCargoTrain ) ) {
|
|| ( true == IsCargoTrain ) ) {
|
||||||
// napełnianie w Oerlikonie
|
// napełnianie w Oerlikonie
|
||||||
/* mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) ); GBH */
|
/* mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) ); GBH */
|
||||||
BrakeLevelSet(gbh_FS);
|
BrakeLevelSet( gbh_FS );
|
||||||
// don't charge the brakes too often, or we risk overcharging
|
// don't charge the brakes too often, or we risk overcharging
|
||||||
BrakeChargingCooldown = -120.0;
|
BrakeChargingCooldown = -120.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
// NOTE: disabled, duplicate of release activation in #5732
|
||||||
else if( Need_BrakeRelease ) {
|
else if( Need_BrakeRelease ) {
|
||||||
Need_BrakeRelease = false;
|
Need_BrakeRelease = false;
|
||||||
mvOccupied->BrakeReleaser( 1 );
|
mvOccupied->BrakeReleaser( 1 );
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition < 0 )
|
if( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition < 0 )
|
||||||
&& ( mvOccupied->EqvtPipePress > ( fReady < 0.25 ? 5.1 : 5.2 ) ) ) {
|
&& ( mvOccupied->EqvtPipePress > ( fReady < 0.25 ? 5.1 : 5.2 ) ) ) {
|
||||||
/* GBH mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); */
|
/* GBH mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); */
|
||||||
BrakeLevelSet(gbh_RP);
|
BrakeLevelSet( gbh_RP );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#if LOGVELOCITY
|
#if LOGVELOCITY
|
||||||
WriteLog("Dist=" + FloatToStrF(ActualProximityDist, ffFixed, 7, 1) +
|
WriteLog("Dist=" + FloatToStrF(ActualProximityDist, ffFixed, 7, 1) +
|
||||||
", VelDesired=" + FloatToStrF(VelDesired, ffFixed, 7, 1) +
|
", VelDesired=" + FloatToStrF(VelDesired, ffFixed, 7, 1) +
|
||||||
@@ -5763,17 +5844,6 @@ TController::UpdateSituation(double dt) {
|
|||||||
AccDesired > 0.0 ) ) {
|
AccDesired > 0.0 ) ) {
|
||||||
// on slopes disengage the brakes only if you actually intend to accelerate
|
// on slopes disengage the brakes only if you actually intend to accelerate
|
||||||
while( true == DecBrake() ) { ; } // jeśli przyspieszamy, to nie hamujemy
|
while( true == DecBrake() ) { ; } // jeśli przyspieszamy, to nie hamujemy
|
||||||
if( ( mvOccupied->BrakePress > 0.4 )
|
|
||||||
&& ( mvOccupied->Hamulec->GetCRP() > 4.9 ) ) {
|
|
||||||
// wyluzuj lokomotywę, to szybciej ruszymy
|
|
||||||
mvOccupied->BrakeReleaser( 1 );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if( mvOccupied->PipePress >= 3.0 ) {
|
|
||||||
// TODO: combine all releaser handling in single decision tree instead of having bits all over the place
|
|
||||||
mvOccupied->BrakeReleaser( 0 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6528,17 +6598,18 @@ std::string TController::NextStop() const
|
|||||||
// dodać godzinę odjazdu
|
// dodać godzinę odjazdu
|
||||||
if (!TrainParams)
|
if (!TrainParams)
|
||||||
return ""; // tu nie powinno nigdy wejść
|
return ""; // tu nie powinno nigdy wejść
|
||||||
std::string nextstop = asNextStop;
|
std::string nextstop = Bezogonkow( asNextStop, true );
|
||||||
TMTableLine *t = TrainParams->TimeTable + TrainParams->StationIndex;
|
TMTableLine *t = TrainParams->TimeTable + TrainParams->StationIndex;
|
||||||
if( t->Ah >= 0 ) {
|
if( t->Ah >= 0 ) {
|
||||||
// przyjazd
|
// przyjazd
|
||||||
nextstop += " przyj." + std::to_string( t->Ah ) + ":"
|
nextstop += " przyj." + std::to_string( t->Ah ) + ":"
|
||||||
+ ( t->Am < 10 ? "0" : "" ) + std::to_string( t->Am );
|
+ to_minutes_str( t->Am, true, 3 );
|
||||||
|
|
||||||
}
|
}
|
||||||
if( t->Dh >= 0 ) {
|
if( t->Dh >= 0 ) {
|
||||||
// jeśli jest godzina odjazdu
|
// jeśli jest godzina odjazdu
|
||||||
nextstop += " odj." + std::to_string( t->Dh ) + ":"
|
nextstop += " odj." + std::to_string( t->Dh ) + ":"
|
||||||
+ ( t->Dm < 10 ? "0" : "" ) + std::to_string( t->Dm );
|
+ to_minutes_str( t->Dm, true, 3 );
|
||||||
}
|
}
|
||||||
return nextstop;
|
return nextstop;
|
||||||
};
|
};
|
||||||
@@ -6607,14 +6678,16 @@ void TController::DirectionForward(bool forward)
|
|||||||
// do przodu w obecnej kabinie
|
// do przodu w obecnej kabinie
|
||||||
while( ( mvOccupied->ActiveDir <= 0 )
|
while( ( mvOccupied->ActiveDir <= 0 )
|
||||||
&& ( mvOccupied->DirectionForward() ) ) {
|
&& ( mvOccupied->DirectionForward() ) ) {
|
||||||
; // all work is done in the header
|
// force scan table update
|
||||||
|
iTableDirection = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// do tyłu w obecnej kabinie
|
// do tyłu w obecnej kabinie
|
||||||
while( ( mvOccupied->ActiveDir >= 0 )
|
while( ( mvOccupied->ActiveDir >= 0 )
|
||||||
&& ( mvOccupied->DirectionBackward() ) ) {
|
&& ( mvOccupied->DirectionBackward() ) ) {
|
||||||
; // all work is done in the header
|
// force scan table update
|
||||||
|
iTableDirection = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( mvOccupied->TrainType == dt_SN61 ) {
|
if( mvOccupied->TrainType == dt_SN61 ) {
|
||||||
|
|||||||
10
Driver.h
10
Driver.h
@@ -201,6 +201,10 @@ public:
|
|||||||
inline
|
inline
|
||||||
TMoverParameters const *Controlling() const {
|
TMoverParameters const *Controlling() const {
|
||||||
return mvControlling; }
|
return mvControlling; }
|
||||||
|
inline
|
||||||
|
TMoverParameters const *Occupied() const {
|
||||||
|
return mvOccupied;
|
||||||
|
}
|
||||||
void DirectionInitial();
|
void DirectionInitial();
|
||||||
void DirectionChange();
|
void DirectionChange();
|
||||||
inline
|
inline
|
||||||
@@ -251,6 +255,7 @@ 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
|
||||||
private:
|
private:
|
||||||
bool Psyche = false;
|
bool Psyche = false;
|
||||||
int HelperState = 0; //stan pomocnika maszynisty
|
int HelperState = 0; //stan pomocnika maszynisty
|
||||||
@@ -280,7 +285,7 @@ private:
|
|||||||
int iCoupler = 0; // maska sprzęgu, jaką należy użyć przy łączeniu (po osiągnięciu trybu Connect), 0 gdy jazda bez łączenia
|
int iCoupler = 0; // maska sprzęgu, jaką należy użyć przy łączeniu (po osiągnięciu trybu Connect), 0 gdy jazda bez łączenia
|
||||||
int iDriverFailCount = 0; // licznik błędów AI
|
int iDriverFailCount = 0; // licznik błędów AI
|
||||||
bool Need_TryAgain = false; // true, jeśli druga pozycja w elektryku nie załapała
|
bool Need_TryAgain = false; // true, jeśli druga pozycja w elektryku nie załapała
|
||||||
bool Need_BrakeRelease = true;
|
// bool Need_BrakeRelease = true;
|
||||||
bool IsAtPassengerStop{ false }; // true if the consist is within acceptable range of w4 post
|
bool IsAtPassengerStop{ false }; // true if the consist is within acceptable range of w4 post
|
||||||
double fMinProximityDist = 30.0; // stawanie między 30 a 60 m przed przeszkodą // minimalna oległość do przeszkody, jaką należy zachować
|
double fMinProximityDist = 30.0; // stawanie między 30 a 60 m przed przeszkodą // minimalna oległość do przeszkody, jaką należy zachować
|
||||||
double fOverhead1 = 3000.0; // informacja o napięciu w sieci trakcyjnej (0=brak drutu, zatrzymaj!)
|
double fOverhead1 = 3000.0; // informacja o napięciu w sieci trakcyjnej (0=brak drutu, zatrzymaj!)
|
||||||
@@ -318,7 +323,6 @@ private:
|
|||||||
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 BrakeCtrlPosition = 0.0; // intermediate position of main brake controller
|
|
||||||
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
|
||||||
@@ -363,7 +367,7 @@ 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;
|
||||||
bool TableAddNew();
|
bool TableAddNew();
|
||||||
bool TableNotFound( basic_event const *Event ) const;
|
bool TableNotFound( basic_event const *Event, double const Distance ) const;
|
||||||
void TableTraceRoute( double fDistance, TDynamicObject *pVehicle );
|
void TableTraceRoute( double fDistance, TDynamicObject *pVehicle );
|
||||||
void TableCheck( double fDistance );
|
void TableCheck( double fDistance );
|
||||||
TCommandType TableUpdate( double &fVelDes, double &fDist, double &fNext, double &fAcc );
|
TCommandType TableUpdate( double &fVelDes, double &fDist, double &fNext, double &fAcc );
|
||||||
|
|||||||
75
DynObj.cpp
75
DynObj.cpp
@@ -2320,7 +2320,9 @@ void TDynamicObject::AttachPrev(TDynamicObject *Object, int iType)
|
|||||||
{ // Ra: doczepia Object na końcu składu (nazwa funkcji może być myląca)
|
{ // Ra: doczepia Object na końcu składu (nazwa funkcji może być myląca)
|
||||||
// Ra: używane tylko przy wczytywaniu scenerii
|
// Ra: używane tylko przy wczytywaniu scenerii
|
||||||
MoverParameters->Attach( iDirection, Object->iDirection ^ 1, Object->MoverParameters, iType, true, false );
|
MoverParameters->Attach( iDirection, Object->iDirection ^ 1, Object->MoverParameters, iType, true, false );
|
||||||
|
// update neighbour data for both affected vehicles
|
||||||
update_neighbours();
|
update_neighbours();
|
||||||
|
Object->update_neighbours();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TDynamicObject::UpdateForce(double dt)
|
bool TDynamicObject::UpdateForce(double dt)
|
||||||
@@ -2782,6 +2784,8 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
|
|
||||||
auto eimic = Min0R(MoverParameters->eimic, MoverParameters->eimicSpeedCtrl);
|
auto eimic = Min0R(MoverParameters->eimic, MoverParameters->eimicSpeedCtrl);
|
||||||
MoverParameters->eimic_real = eimic;
|
MoverParameters->eimic_real = eimic;
|
||||||
|
if (MoverParameters->EIMCtrlType == 2 && MoverParameters->MainCtrlPos == 0)
|
||||||
|
eimic = -1.0;
|
||||||
MoverParameters->SendCtrlToNext("EIMIC", Max0R(0, eimic), MoverParameters->CabNo);
|
MoverParameters->SendCtrlToNext("EIMIC", Max0R(0, eimic), MoverParameters->CabNo);
|
||||||
auto LBR = Max0R(-eimic, 0);
|
auto LBR = Max0R(-eimic, 0);
|
||||||
auto eim_lb = (Mechanik->AIControllFlag || !MoverParameters->LocHandleTimeTraxx ? 0 : MoverParameters->eim_localbrake);
|
auto eim_lb = (Mechanik->AIControllFlag || !MoverParameters->LocHandleTimeTraxx ? 0 : MoverParameters->eim_localbrake);
|
||||||
@@ -2891,6 +2895,10 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
&& ( MoverParameters->BrakeOpModeFlag & bom_MED ) ) ) {
|
&& ( MoverParameters->BrakeOpModeFlag & bom_MED ) ) ) {
|
||||||
FzadED = std::min( Fzad, FmaxED );
|
FzadED = std::min( Fzad, FmaxED );
|
||||||
}
|
}
|
||||||
|
if (MoverParameters->EIMCtrlType == 2 && MoverParameters->MainCtrlPos < 2 && MoverParameters->eimic > -0.999)
|
||||||
|
{
|
||||||
|
FzadED = std::min(FzadED, MED_oldFED);
|
||||||
|
}
|
||||||
if ((MoverParameters->BrakeCtrlPos == MoverParameters->Handle->GetPos(bh_EB))
|
if ((MoverParameters->BrakeCtrlPos == MoverParameters->Handle->GetPos(bh_EB))
|
||||||
&& (MoverParameters->eimc[eimc_p_abed] < 0.001))
|
&& (MoverParameters->eimc[eimc_p_abed] < 0.001))
|
||||||
FzadED = 0; //pętla bezpieczeństwa - bez ED
|
FzadED = 0; //pętla bezpieczeństwa - bez ED
|
||||||
@@ -3068,6 +3076,8 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
delete[] FzED;
|
delete[] FzED;
|
||||||
delete[] FzEP;
|
delete[] FzEP;
|
||||||
delete[] FmaxEP;
|
delete[] FmaxEP;
|
||||||
|
|
||||||
|
MED_oldFED = FzadED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mechanik->UpdateSituation(dt1); // przebłyski świadomości AI
|
Mechanik->UpdateSituation(dt1); // przebłyski świadomości AI
|
||||||
@@ -4345,10 +4355,6 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
|||||||
m_materialdata.textures_alpha |= 0x08080008;
|
m_materialdata.textures_alpha |= 0x08080008;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( false == MoverParameters->LoadAttributes.empty() ) {
|
|
||||||
// Ra: tu wczytywanie modelu ładunku jest w porządku
|
|
||||||
mdLoad = LoadMMediaFile_mdload( MoverParameters->LoadType.name );
|
|
||||||
}
|
|
||||||
Global.asCurrentTexturePath = szTexturePath; // z powrotem defaultowa sciezka do tekstur
|
Global.asCurrentTexturePath = szTexturePath; // z powrotem defaultowa sciezka do tekstur
|
||||||
do {
|
do {
|
||||||
token = "";
|
token = "";
|
||||||
@@ -4930,6 +4936,18 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
|||||||
} while( ( token != "" )
|
} while( ( token != "" )
|
||||||
&& ( token != "endmodels" ) );
|
&& ( token != "endmodels" ) );
|
||||||
|
|
||||||
|
if( false == MoverParameters->LoadAttributes.empty() ) {
|
||||||
|
// Ra: tu wczytywanie modelu ładunku jest w porządku
|
||||||
|
|
||||||
|
// bieżąca ścieżka do tekstur to dynamic/...
|
||||||
|
Global.asCurrentTexturePath = asBaseDir;
|
||||||
|
|
||||||
|
mdLoad = LoadMMediaFile_mdload( MoverParameters->LoadType.name );
|
||||||
|
|
||||||
|
// z powrotem defaultowa sciezka do tekstur
|
||||||
|
Global.asCurrentTexturePath = std::string( szTexturePath );
|
||||||
|
}
|
||||||
|
|
||||||
} // models
|
} // models
|
||||||
|
|
||||||
else if( token == "sounds:" ) {
|
else if( token == "sounds:" ) {
|
||||||
@@ -6106,30 +6124,32 @@ 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...
|
||||||
TDynamicObject *d = this; // zaczynamy od aktualnego
|
if( MoverParameters->Power > 1.0 ) { return this; }
|
||||||
if( ( d->MoverParameters->TrainType == dt_EZT )
|
|
||||||
|| ( d->MoverParameters->TrainType == dt_DMU ) ) {
|
auto const couplingtype { (
|
||||||
// na razie dotyczy to EZT
|
( MoverParameters->TrainType == dt_EZT )
|
||||||
if( ( d->NextConnected() != nullptr )
|
|| ( MoverParameters->TrainType == dt_DMU ) ) ?
|
||||||
&& ( true == TestFlag( d->MoverParameters->Couplers[ end::rear ].AllowedFlag, coupling::permanent ) ) ) {
|
coupling::permanent :
|
||||||
// gdy jest człon od sprzęgu 1, a sprzęg łączony warsztatowo (powiedzmy)
|
coupling::control
|
||||||
if( ( d->MoverParameters->Power < 1.0 )
|
};
|
||||||
&& ( d->NextConnected()->MoverParameters->Power > 1.0 ) ) {
|
// try first to look towards the rear
|
||||||
// my nie mamy mocy, ale ten drugi ma
|
auto *d = this; // zaczynamy od aktualnego
|
||||||
d = d->NextConnected(); // będziemy sterować tym z mocą
|
|
||||||
}
|
while( ( d = d->NextC( couplingtype ) ) != nullptr ) {
|
||||||
}
|
if( d->MoverParameters->Power > 1.0 ) {
|
||||||
else if( ( d->PrevConnected() != nullptr )
|
return d;
|
||||||
&& ( true == TestFlag( d->MoverParameters->Couplers[ end::front ].AllowedFlag, coupling::permanent ) ) ) {
|
|
||||||
// gdy jest człon od sprzęgu 0, a sprzęg łączony warsztatowo (powiedzmy)
|
|
||||||
if( ( d->MoverParameters->Power < 1.0 )
|
|
||||||
&& ( d->PrevConnected()->MoverParameters->Power > 1.0 ) ) {
|
|
||||||
// my nie mamy mocy, ale ten drugi ma
|
|
||||||
d = d->PrevConnected(); // będziemy sterować tym z mocą
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return d;
|
// if we didn't yet find a suitable vehicle try in the other direction
|
||||||
|
d = this; // zaczynamy od aktualnego
|
||||||
|
|
||||||
|
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;
|
||||||
};
|
};
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -6610,7 +6630,8 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
|
|||||||
// youBy - przenioslem, bo diesel tez moze miec turbo
|
// youBy - przenioslem, bo diesel tez moze miec turbo
|
||||||
if( Vehicle.TurboTest > 0 ) {
|
if( Vehicle.TurboTest > 0 ) {
|
||||||
// udawanie turbo:
|
// udawanie turbo:
|
||||||
auto const goalpitch { std::max( 0.025, ( engine_volume + engine_turbo.m_frequencyoffset ) * engine_turbo.m_frequencyfactor ) };
|
auto const pitch_diesel { Vehicle.EngineType == TEngineType::DieselEngine ? Vehicle.enrot / Vehicle.dizel_nmax : 0 };
|
||||||
|
auto const goalpitch { std::max( 0.025, ( engine_volume * pitch_diesel + engine_turbo.m_frequencyoffset ) * engine_turbo.m_frequencyfactor ) };
|
||||||
auto const goalvolume { (
|
auto const goalvolume { (
|
||||||
( ( Vehicle.MainCtrlPos >= Vehicle.TurboTest ) && ( Vehicle.enrot > 0.1 ) ) ?
|
( ( Vehicle.MainCtrlPos >= Vehicle.TurboTest ) && ( Vehicle.enrot > 0.1 ) ) ?
|
||||||
std::max( 0.0, ( engine_turbo_pitch + engine_turbo.m_amplitudeoffset ) * engine_turbo.m_amplitudefactor ) :
|
std::max( 0.0, ( engine_turbo_pitch + engine_turbo.m_amplitudeoffset ) * engine_turbo.m_amplitudefactor ) :
|
||||||
|
|||||||
1
DynObj.h
1
DynObj.h
@@ -659,6 +659,7 @@ private:
|
|||||||
double MEDLogTime = 0;
|
double MEDLogTime = 0;
|
||||||
double MEDLogInactiveTime = 0;
|
double MEDLogInactiveTime = 0;
|
||||||
int MEDLogCount = 0;
|
int MEDLogCount = 0;
|
||||||
|
double MED_oldFED = 0;
|
||||||
|
|
||||||
// vehicle shaking calculations
|
// vehicle shaking calculations
|
||||||
// TBD, TODO: make an object out of it
|
// TBD, TODO: make an object out of it
|
||||||
|
|||||||
@@ -127,7 +127,13 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
// selected device for audio renderer
|
// selected device for audio renderer
|
||||||
Parser.getTokens();
|
Parser.getTokens();
|
||||||
Parser >> AudioVolume;
|
Parser >> AudioVolume;
|
||||||
AudioVolume = clamp( AudioVolume, 0.0f, 2.f );
|
AudioVolume = clamp( AudioVolume, 0.f, 2.f );
|
||||||
|
}
|
||||||
|
else if( token == "sound.volume.radio" ) {
|
||||||
|
// selected device for audio renderer
|
||||||
|
Parser.getTokens();
|
||||||
|
Parser >> RadioVolume;
|
||||||
|
RadioVolume = clamp( RadioVolume, 0.f, 1.f );
|
||||||
}
|
}
|
||||||
else if (token == "sound.maxsources") {
|
else if (token == "sound.maxsources") {
|
||||||
Parser.getTokens();
|
Parser.getTokens();
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ struct global_settings {
|
|||||||
bool bLiveTraction{ true };
|
bool bLiveTraction{ true };
|
||||||
float Overcast{ 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
|
float Overcast{ 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
|
||||||
glm::vec3 FogColor = { 0.6f, 0.7f, 0.8f };
|
glm::vec3 FogColor = { 0.6f, 0.7f, 0.8f };
|
||||||
double fFogStart{ 1700 };
|
|
||||||
double fFogEnd{ 2000 };
|
double fFogEnd{ 2000 };
|
||||||
std::string Season{}; // season of the year, based on simulation date
|
std::string Season{}; // season of the year, based on simulation date
|
||||||
std::string Weather{ "cloudy:" }; // current weather
|
std::string Weather{ "cloudy:" }; // current weather
|
||||||
@@ -136,7 +135,8 @@ struct global_settings {
|
|||||||
double fFpsMax{ 65.0 }; // górna granica FPS, przy której promień scenerii będzie zwiększany
|
double fFpsMax{ 65.0 }; // górna granica FPS, przy której promień scenerii będzie zwiększany
|
||||||
// audio
|
// audio
|
||||||
bool bSoundEnabled{ true };
|
bool bSoundEnabled{ true };
|
||||||
float AudioVolume{ 1.25f };
|
float AudioVolume{ 1.f };
|
||||||
|
float RadioVolume{ 0.75f };
|
||||||
int audio_max_sources = 30;
|
int audio_max_sources = 30;
|
||||||
std::string AudioRenderer;
|
std::string AudioRenderer;
|
||||||
// input
|
// input
|
||||||
|
|||||||
@@ -767,6 +767,7 @@ private:
|
|||||||
// ld inputs
|
// ld inputs
|
||||||
bool lock_enabled { true };
|
bool lock_enabled { true };
|
||||||
bool step_enabled { true };
|
bool step_enabled { true };
|
||||||
|
bool remote_only { false }; // door ignores local control signals
|
||||||
// internal data
|
// internal data
|
||||||
int permit_preset { -1 }; // curent position of preset selection switch
|
int permit_preset { -1 }; // curent position of preset selection switch
|
||||||
// vehicle parts
|
// vehicle parts
|
||||||
@@ -1163,6 +1164,7 @@ public:
|
|||||||
bool CompressorAllowLocal{ true }; // local device state override (most units don't have this fitted so it's set to true not to intefere)
|
bool CompressorAllowLocal{ true }; // local device state override (most units don't have this fitted so it's set to true not to intefere)
|
||||||
bool CompressorGovernorLock{ false }; // indicates whether compressor pressure switch was activated due to reaching cut-out pressure
|
bool CompressorGovernorLock{ false }; // indicates whether compressor pressure switch was activated due to reaching cut-out pressure
|
||||||
start_t CompressorStart{ start_t::manual }; // whether the compressor is started manually, or another way
|
start_t CompressorStart{ start_t::manual }; // whether the compressor is started manually, or another way
|
||||||
|
start_t PantographCompressorStart{ start_t::manual };
|
||||||
// TODO converter parameters, for when we start cleaning up mover parameters
|
// TODO converter parameters, for when we start cleaning up mover parameters
|
||||||
start_t ConverterStart{ start_t::manual }; // whether converter is started manually, or by other means
|
start_t ConverterStart{ start_t::manual }; // whether converter is started manually, or by other means
|
||||||
float ConverterStartDelay{ 0.0f }; // delay (in seconds) before the converter is started, once its activation conditions are met
|
float ConverterStartDelay{ 0.0f }; // delay (in seconds) before the converter is started, once its activation conditions are met
|
||||||
@@ -1311,6 +1313,8 @@ public:
|
|||||||
double eim_localbrake = 0; /*nastawa hamowania dodatkowego pneumatycznego lokomotywy*/
|
double eim_localbrake = 0; /*nastawa hamowania dodatkowego pneumatycznego lokomotywy*/
|
||||||
int EIMCtrlType = 0; /*rodzaj wariantu zadajnika jazdy*/
|
int EIMCtrlType = 0; /*rodzaj wariantu zadajnika jazdy*/
|
||||||
bool SpeedCtrlTypeTime = false; /*czy tempomat sterowany czasowo*/
|
bool SpeedCtrlTypeTime = false; /*czy tempomat sterowany czasowo*/
|
||||||
|
int SpeedCtrlAutoTurnOffFlag = 0; /*czy tempomat sam się wyłącza*/
|
||||||
|
bool EIMCtrlAdditionalZeros = false; /*czy ma dodatkowe zero jazdy i zero hamowania */
|
||||||
double eimv_pr = 0; /*realizowany procent dostepnej sily rozruchu/hamowania*/
|
double eimv_pr = 0; /*realizowany procent dostepnej sily rozruchu/hamowania*/
|
||||||
double eimv[21];
|
double eimv[21];
|
||||||
static std::vector<std::string> const eimv_labels;
|
static std::vector<std::string> const eimv_labels;
|
||||||
@@ -1345,8 +1349,6 @@ public:
|
|||||||
bool PantRearUp = false;
|
bool PantRearUp = false;
|
||||||
bool PantFrontSP = true; //dzwiek patykow 'Winger 010304
|
bool PantFrontSP = true; //dzwiek patykow 'Winger 010304
|
||||||
bool PantRearSP = true;
|
bool PantRearSP = true;
|
||||||
int PantFrontStart = 0; //stan patykow 'Winger 160204
|
|
||||||
int PantRearStart = 0;
|
|
||||||
double PantFrontVolt = 0.0; //pantograf pod napieciem? 'Winger 160404
|
double PantFrontVolt = 0.0; //pantograf pod napieciem? 'Winger 160404
|
||||||
double PantRearVolt = 0.0;
|
double PantRearVolt = 0.0;
|
||||||
// TODO: move these switch types where they belong, cabin definition
|
// TODO: move these switch types where they belong, cabin definition
|
||||||
@@ -1554,6 +1556,7 @@ public:
|
|||||||
bool PermitDoors( side const Door, bool const State = true, range_t const Notify = range_t::consist );
|
bool PermitDoors( side const Door, bool const State = true, range_t const Notify = range_t::consist );
|
||||||
bool ChangeDoorPermitPreset( int const Change, range_t const Notify = range_t::consist );
|
bool ChangeDoorPermitPreset( int const Change, range_t const Notify = range_t::consist );
|
||||||
bool PermitDoorStep( bool const State, range_t const Notify = range_t::consist );
|
bool PermitDoorStep( bool const State, range_t const Notify = range_t::consist );
|
||||||
|
bool ChangeDoorControlMode( bool const State, range_t const Notify = range_t::consist );
|
||||||
bool OperateDoors( side const Door, bool const State, range_t const Notify = range_t::consist );
|
bool OperateDoors( side const Door, bool const State, range_t const Notify = range_t::consist );
|
||||||
bool LockDoors( bool const State, range_t const Notify = range_t::consist );
|
bool LockDoors( bool const State, range_t const Notify = range_t::consist );
|
||||||
bool signal_departure( bool const State, range_t const Notify = range_t::consist ); // toggles departure warning
|
bool signal_departure( bool const State, range_t const Notify = range_t::consist ); // toggles departure warning
|
||||||
|
|||||||
@@ -653,11 +653,18 @@ void TMoverParameters::UpdatePantVolume(double dt)
|
|||||||
{ // KURS90 - sprężarka pantografów; Ra 2014-07: teraz jest to zbiornik rozrządu, chociaż to jeszcze nie tak
|
{ // KURS90 - sprężarka pantografów; Ra 2014-07: teraz jest to zbiornik rozrządu, chociaż to jeszcze nie tak
|
||||||
|
|
||||||
// check the pantograph compressor while at it
|
// check the pantograph compressor while at it
|
||||||
if( PantCompFlag ) {
|
if( ( PantPress < 4.2 )
|
||||||
if( ( false == Battery )
|
&& ( ( PantographCompressorStart == start_t::automatic )
|
||||||
&& ( false == ConverterFlag ) ) {
|
|| ( PantographCompressorStart == start_t::manualwithautofallback ) )
|
||||||
PantCompFlag = false;
|
&& ( ( true == PantRearUp )
|
||||||
}
|
|| ( true == PantFrontUp ) ) ) {
|
||||||
|
// automatic start if the pressure is too low
|
||||||
|
PantCompFlag = true;
|
||||||
|
}
|
||||||
|
if( ( true == PantCompFlag )
|
||||||
|
&& ( false == Battery )
|
||||||
|
&& ( false == ConverterFlag ) ) {
|
||||||
|
PantCompFlag = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EnginePowerSource.SourceType == TPowerSource::CurrentCollector) // tylko jeśli pantografujący
|
if (EnginePowerSource.SourceType == TPowerSource::CurrentCollector) // tylko jeśli pantografujący
|
||||||
@@ -1684,7 +1691,9 @@ bool TMoverParameters::IncMainCtrl(int CtrlSpeed)
|
|||||||
else {
|
else {
|
||||||
++MainCtrlPos;
|
++MainCtrlPos;
|
||||||
OK = true;
|
OK = true;
|
||||||
}
|
if ((EIMCtrlType == 0) && (SpeedCtrlAutoTurnOffFlag == 1) && (MainCtrlActualPos != MainCtrlPos))
|
||||||
|
DecScndCtrl(2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1846,6 +1855,8 @@ bool TMoverParameters::DecMainCtrl(int CtrlSpeed)
|
|||||||
{
|
{
|
||||||
MainCtrlPos--;
|
MainCtrlPos--;
|
||||||
OK = true;
|
OK = true;
|
||||||
|
if ((EIMCtrlType == 0) && (SpeedCtrlAutoTurnOffFlag == 1) && (MainCtrlActualPos != MainCtrlPos))
|
||||||
|
DecScndCtrl(2);
|
||||||
}
|
}
|
||||||
else if (CtrlSpeed > 1)
|
else if (CtrlSpeed > 1)
|
||||||
OK = (DecMainCtrl(1) && DecMainCtrl(2)); // CtrlSpeed-1);
|
OK = (DecMainCtrl(1) && DecMainCtrl(2)); // CtrlSpeed-1);
|
||||||
@@ -1987,13 +1998,17 @@ bool TMoverParameters::IncScndCtrl(int CtrlSpeed)
|
|||||||
if (LastRelayTime > CtrlDelay)
|
if (LastRelayTime > CtrlDelay)
|
||||||
LastRelayTime = 0;
|
LastRelayTime = 0;
|
||||||
|
|
||||||
if ((OK) && (EngineType == TEngineType::ElectricInductionMotor) && (ScndCtrlPosNo == 1))
|
if ((OK) && (EngineType == TEngineType::ElectricInductionMotor) && (ScndCtrlPosNo == 1) && (MainCtrlPos>0))
|
||||||
{
|
{
|
||||||
// NOTE: round() already adds 0.5, are the ones added here as well correct?
|
// NOTE: round() already adds 0.5, are the ones added here as well correct?
|
||||||
if ((Vmax < 250))
|
if ((Vmax < 250))
|
||||||
ScndCtrlActualPos = Round(Vel);
|
ScndCtrlActualPos = Round(Vel);
|
||||||
else
|
else
|
||||||
ScndCtrlActualPos = Round(Vel * 0.5);
|
ScndCtrlActualPos = Round(Vel * 0.5);
|
||||||
|
if ((EIMCtrlType == 0)&&(SpeedCtrlAutoTurnOffFlag == 1))
|
||||||
|
{
|
||||||
|
MainCtrlActualPos = MainCtrlPos;
|
||||||
|
}
|
||||||
SendCtrlToNext("SpeedCntrl", ScndCtrlActualPos, CabNo);
|
SendCtrlToNext("SpeedCntrl", ScndCtrlActualPos, CabNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3901,7 +3916,18 @@ void TMoverParameters::ComputeConstans(void)
|
|||||||
}
|
}
|
||||||
Ff = TotalMassxg * (BearingF + RollF * V * V / 10.0) / 1000.0;
|
Ff = TotalMassxg * (BearingF + RollF * V * V / 10.0) / 1000.0;
|
||||||
// dorobic liczenie temperatury lozyska!
|
// dorobic liczenie temperatury lozyska!
|
||||||
FrictConst1 = ((TotalMassxg * RollF) / 10000.0) + (Cx * Dim.W * Dim.H);
|
FrictConst1 = ( TotalMassxg * RollF ) / 10000.0;
|
||||||
|
// drag calculation
|
||||||
|
{
|
||||||
|
// NOTE: draft effect of previous vehicle is simplified and doesn't have much to do with reality
|
||||||
|
auto const *previousvehicle { Couplers[ ( V >= 0.0 ? end::front : end::rear ) ].Connected };
|
||||||
|
auto dragarea { Dim.W * Dim.H };
|
||||||
|
if( previousvehicle ) {
|
||||||
|
dragarea = std::max( 0.0, dragarea - ( 0.85 * previousvehicle->Dim.W * previousvehicle->Dim.H ) );
|
||||||
|
}
|
||||||
|
FrictConst1 += Cx * dragarea;
|
||||||
|
}
|
||||||
|
|
||||||
Curvature = abs(RunningShape.R); // zero oznacza nieskończony promień
|
Curvature = abs(RunningShape.R); // zero oznacza nieskończony promień
|
||||||
if (Curvature > 0.0)
|
if (Curvature > 0.0)
|
||||||
Curvature = 1.0 / Curvature;
|
Curvature = 1.0 / Curvature;
|
||||||
@@ -4416,7 +4442,7 @@ double TMoverParameters::TractionForce( double dt ) {
|
|||||||
|
|
||||||
if( enrot != tmp ) {
|
if( enrot != tmp ) {
|
||||||
enrot = clamp(
|
enrot = clamp(
|
||||||
enrot + ( dt / 1.25 ) * ( // TODO: equivalent of dizel_aim instead of fixed inertia
|
enrot + ( dt / dizel_AIM ) * (
|
||||||
enrot < tmp ?
|
enrot < tmp ?
|
||||||
1.0 :
|
1.0 :
|
||||||
-2.0 ), // NOTE: revolutions drop faster than they rise, maybe? TBD: maybe not
|
-2.0 ), // NOTE: revolutions drop faster than they rise, maybe? TBD: maybe not
|
||||||
@@ -5915,7 +5941,6 @@ bool TMoverParameters::PantFront( bool const State, range_t const Notify )
|
|||||||
if( PantFrontUp != State ) {
|
if( PantFrontUp != State ) {
|
||||||
PantFrontUp = State;
|
PantFrontUp = State;
|
||||||
if( State == true ) {
|
if( State == true ) {
|
||||||
PantFrontStart = 0;
|
|
||||||
if( Notify != range_t::local ) {
|
if( Notify != range_t::local ) {
|
||||||
// wysłanie wyłączenia do pozostałych?
|
// wysłanie wyłączenia do pozostałych?
|
||||||
SendCtrlToNext(
|
SendCtrlToNext(
|
||||||
@@ -5926,7 +5951,6 @@ bool TMoverParameters::PantFront( bool const State, range_t const Notify )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PantFrontStart = 1;
|
|
||||||
if( Notify != range_t::local ) {
|
if( Notify != range_t::local ) {
|
||||||
// wysłanie wyłączenia do pozostałych?
|
// wysłanie wyłączenia do pozostałych?
|
||||||
SendCtrlToNext(
|
SendCtrlToNext(
|
||||||
@@ -5968,7 +5992,6 @@ bool TMoverParameters::PantRear( bool const State, range_t const Notify )
|
|||||||
if( PantRearUp != State ) {
|
if( PantRearUp != State ) {
|
||||||
PantRearUp = State;
|
PantRearUp = State;
|
||||||
if( State == true ) {
|
if( State == true ) {
|
||||||
PantRearStart = 0;
|
|
||||||
if( Notify != range_t::local ) {
|
if( Notify != range_t::local ) {
|
||||||
// wysłanie wyłączenia do pozostałych?
|
// wysłanie wyłączenia do pozostałych?
|
||||||
SendCtrlToNext(
|
SendCtrlToNext(
|
||||||
@@ -5979,7 +6002,6 @@ bool TMoverParameters::PantRear( bool const State, range_t const Notify )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PantRearStart = 1;
|
|
||||||
if( Notify != range_t::local ) {
|
if( Notify != range_t::local ) {
|
||||||
// wysłanie wyłączenia do pozostałych?
|
// wysłanie wyłączenia do pozostałych?
|
||||||
SendCtrlToNext(
|
SendCtrlToNext(
|
||||||
@@ -6014,6 +6036,13 @@ void TMoverParameters::CheckEIMIC(double dt)
|
|||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
eimic = (LocalBrakeRatio() > 0.01 ? -LocalBrakeRatio() : (double)MainCtrlPos / (double)MainCtrlPosNo);
|
eimic = (LocalBrakeRatio() > 0.01 ? -LocalBrakeRatio() : (double)MainCtrlPos / (double)MainCtrlPosNo);
|
||||||
|
if (EIMCtrlAdditionalZeros)
|
||||||
|
{
|
||||||
|
if (eimic > 0.001)
|
||||||
|
eimic = std::max(0.002, eimic * (double)MainCtrlPosNo / ((double)MainCtrlPosNo - 1.0) - 1.0 / ((double)MainCtrlPosNo - 1.0));
|
||||||
|
if (eimic < -0.001)
|
||||||
|
eimic = std::min(-0.002, eimic * (double)LocalBrakePosNo / ((double)LocalBrakePosNo - 1.0) + 1.0 / ((double)LocalBrakePosNo - 1.0));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
switch (MainCtrlPos)
|
switch (MainCtrlPos)
|
||||||
@@ -6064,25 +6093,34 @@ void TMoverParameters::CheckEIMIC(double dt)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
switch (MainCtrlPos)
|
if ((MainCtrlActualPos != MainCtrlPos) || (LastRelayTime>InitialCtrlDelay))
|
||||||
{
|
{
|
||||||
case 0:
|
double delta = (MainCtrlActualPos == MainCtrlPos ? dt*CtrlDelay : 0.01);
|
||||||
eimic = -1.0;
|
switch (MainCtrlPos)
|
||||||
break;
|
{
|
||||||
case 1:
|
case 0:
|
||||||
eimic -= clamp(1.0 + eimic, 0.0, dt*0.15); //odejmuj do -1
|
case 1:
|
||||||
if (eimic > 0) eimic = 0;
|
eimic -= clamp(1.0 + eimic, 0.0, delta); //odejmuj do -1
|
||||||
break;
|
if (eimic > 0) eimic = 0;
|
||||||
case 2:
|
break;
|
||||||
eimic -= clamp(0.0 + eimic, 0.0, dt*0.15); //odejmuj do 0
|
case 2:
|
||||||
break;
|
eimic -= clamp(0.0 + eimic, 0.0, delta); //odejmuj do 0
|
||||||
case 3:
|
break;
|
||||||
eimic += clamp(0.0 - eimic, 0.0, dt*0.15); //dodawaj do 0
|
case 3:
|
||||||
break;
|
eimic += clamp(0.0 - eimic, 0.0, delta); //dodawaj do 0
|
||||||
case 4:
|
break;
|
||||||
eimic += clamp(1.0 - eimic, 0.0, dt*0.15); //dodawaj do 1
|
case 4:
|
||||||
if (eimic < 0) eimic = 0;
|
eimic += clamp(1.0 - eimic, 0.0, delta); //dodawaj do 1
|
||||||
break;
|
if (eimic < 0) eimic = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (MainCtrlActualPos == MainCtrlPos)
|
||||||
|
LastRelayTime += dt;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LastRelayTime = 0;
|
||||||
|
MainCtrlActualPos = MainCtrlPos;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
@@ -6090,7 +6128,11 @@ void TMoverParameters::CheckEIMIC(double dt)
|
|||||||
eimic += clamp(UniCtrlList[MainCtrlPos].SetCtrlVal - eimic, 0.0, dt * UniCtrlList[MainCtrlPos].SpeedUp); //dodawaj do X
|
eimic += clamp(UniCtrlList[MainCtrlPos].SetCtrlVal - eimic, 0.0, dt * UniCtrlList[MainCtrlPos].SpeedUp); //dodawaj do X
|
||||||
eimic = clamp(eimic, UniCtrlList[MainCtrlPos].MinCtrlVal, UniCtrlList[MainCtrlPos].MaxCtrlVal);
|
eimic = clamp(eimic, UniCtrlList[MainCtrlPos].MinCtrlVal, UniCtrlList[MainCtrlPos].MaxCtrlVal);
|
||||||
}
|
}
|
||||||
eimic = clamp(eimic, -1.0, 1.0);
|
auto const eimicpowerenabled {
|
||||||
|
( ( true == Mains ) || ( Power == 0.0 ) )
|
||||||
|
&& ( ( Doors.instances[ side::left ].open_permit == false )
|
||||||
|
&& ( Doors.instances[ side::right ].open_permit == false ) ) };
|
||||||
|
eimic = clamp(eimic, -1.0, eimicpowerenabled ? 1.0 : 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TMoverParameters::CheckSpeedCtrl()
|
void TMoverParameters::CheckSpeedCtrl()
|
||||||
@@ -6910,12 +6952,7 @@ bool TMoverParameters::PermitDoors( side const Door, bool const State, range_t c
|
|||||||
|
|
||||||
bool const initialstate { Doors.instances[Door].open_permit };
|
bool const initialstate { Doors.instances[Door].open_permit };
|
||||||
|
|
||||||
if( ( false == Doors.permit_presets.empty() ) // HACK: for cases where preset switch is used before battery
|
Doors.instances[ Door ].open_permit = State;
|
||||||
|| ( ( true == Battery )
|
|
||||||
&& ( false == Doors.is_locked ) ) ) {
|
|
||||||
|
|
||||||
Doors.instances[ Door ].open_permit = State;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Notify != range_t::local ) {
|
if( Notify != range_t::local ) {
|
||||||
|
|
||||||
@@ -6934,6 +6971,34 @@ bool TMoverParameters::PermitDoors( side const Door, bool const State, range_t c
|
|||||||
return ( Doors.instances[ Door ].open_permit != initialstate );
|
return ( Doors.instances[ Door ].open_permit != initialstate );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TMoverParameters::ChangeDoorControlMode( bool const State, range_t const Notify ) {
|
||||||
|
|
||||||
|
auto const initialstate { Doors.remote_only };
|
||||||
|
|
||||||
|
Doors.remote_only = State;
|
||||||
|
if( Notify != range_t::local ) {
|
||||||
|
// wysłanie wyłączenia do pozostałych?
|
||||||
|
SendCtrlToNext(
|
||||||
|
"DoorMode",
|
||||||
|
( State == true ?
|
||||||
|
1 :
|
||||||
|
0 ),
|
||||||
|
CabNo,
|
||||||
|
( Notify == range_t::unit ?
|
||||||
|
coupling::control | coupling::permanent :
|
||||||
|
coupling::control ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( true == State ) {
|
||||||
|
// when door are put in remote control mode they're automatically open
|
||||||
|
// TBD, TODO: make it dependant on config switch?
|
||||||
|
OperateDoors( side::left, true );
|
||||||
|
OperateDoors( side::right, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( Doors.step_enabled != initialstate );
|
||||||
|
}
|
||||||
|
|
||||||
bool TMoverParameters::OperateDoors( side const Door, bool const State, range_t const Notify ) {
|
bool TMoverParameters::OperateDoors( side const Door, bool const State, range_t const Notify ) {
|
||||||
|
|
||||||
auto &door { Doors.instances[ Door ] };
|
auto &door { Doors.instances[ Door ] };
|
||||||
@@ -7041,15 +7106,17 @@ TMoverParameters::update_doors( double const Deltatime ) {
|
|||||||
|
|
||||||
// NBMX Obsluga drzwi, MC: zuniwersalnione
|
// NBMX Obsluga drzwi, MC: zuniwersalnione
|
||||||
auto const localopencontrol {
|
auto const localopencontrol {
|
||||||
( Doors.open_control == control_t::passenger )
|
( false == Doors.remote_only )
|
||||||
|| ( Doors.open_control == control_t::mixed ) };
|
&& ( ( Doors.open_control == control_t::passenger )
|
||||||
|
|| ( Doors.open_control == control_t::mixed ) ) };
|
||||||
auto const remoteopencontrol {
|
auto const remoteopencontrol {
|
||||||
( Doors.open_control == control_t::driver )
|
( Doors.open_control == control_t::driver )
|
||||||
|| ( Doors.open_control == control_t::conductor )
|
|| ( Doors.open_control == control_t::conductor )
|
||||||
|| ( Doors.open_control == control_t::mixed ) };
|
|| ( Doors.open_control == control_t::mixed ) };
|
||||||
auto const localclosecontrol {
|
auto const localclosecontrol {
|
||||||
( Doors.close_control == control_t::passenger )
|
( false == Doors.remote_only )
|
||||||
|| ( Doors.close_control == control_t::mixed ) };
|
&& ( ( Doors.close_control == control_t::passenger )
|
||||||
|
|| ( Doors.close_control == control_t::mixed ) ) };
|
||||||
auto const remoteclosecontrol {
|
auto const remoteclosecontrol {
|
||||||
( Doors.close_control == control_t::driver )
|
( Doors.close_control == control_t::driver )
|
||||||
|| ( Doors.close_control == control_t::conductor )
|
|| ( Doors.close_control == control_t::conductor )
|
||||||
@@ -7077,13 +7144,18 @@ TMoverParameters::update_doors( double const Deltatime ) {
|
|||||||
&& ( door.step_position <= 0.f );
|
&& ( door.step_position <= 0.f );
|
||||||
|
|
||||||
door.local_open = door.local_open && ( false == door.is_open ) && ( ( false == Doors.permit_needed ) || door.open_permit );
|
door.local_open = door.local_open && ( false == door.is_open ) && ( ( false == Doors.permit_needed ) || door.open_permit );
|
||||||
door.remote_open = door.remote_open && ( false == door.is_open ) && ( ( false == Doors.permit_needed ) || door.open_permit );
|
door.remote_open = ( door.remote_open || Doors.remote_only ) && ( false == door.is_open ) && ( ( false == Doors.permit_needed ) || door.open_permit );
|
||||||
door.local_close = door.local_close && ( false == door.is_closed );
|
door.local_close = door.local_close && ( false == door.is_closed );
|
||||||
door.remote_close = door.remote_close && ( false == door.is_closed );
|
door.remote_close = door.remote_close && ( false == door.is_closed );
|
||||||
|
|
||||||
|
auto const autoopenrequest {
|
||||||
|
( Doors.open_control == control_t::autonomous )
|
||||||
|
&& ( ( false == Doors.permit_needed ) || door.open_permit )
|
||||||
|
};
|
||||||
auto const openrequest {
|
auto const openrequest {
|
||||||
( localopencontrol && door.local_open )
|
( localopencontrol && door.local_open )
|
||||||
|| ( remoteopencontrol && door.remote_open ) };
|
|| ( remoteopencontrol && door.remote_open )
|
||||||
|
|| ( autoopenrequest && ( false == door.is_open ) ) };
|
||||||
|
|
||||||
auto const autocloserequest {
|
auto const autocloserequest {
|
||||||
( ( Doors.auto_velocity != -1.f ) && ( Vel > Doors.auto_velocity ) )
|
( ( Doors.auto_velocity != -1.f ) && ( Vel > Doors.auto_velocity ) )
|
||||||
@@ -8375,12 +8447,6 @@ void TMoverParameters::LoadFIZ_Doors( std::string const &line ) {
|
|||||||
lookup != doorcontrols.end() ?
|
lookup != doorcontrols.end() ?
|
||||||
lookup->second :
|
lookup->second :
|
||||||
control_t::passenger;
|
control_t::passenger;
|
||||||
|
|
||||||
if( Doors.close_control == control_t::autonomous ) {
|
|
||||||
// convert legacy method
|
|
||||||
Doors.close_control = control_t::passenger;
|
|
||||||
Doors.auto_velocity = 10.0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// automatic closing conditions
|
// automatic closing conditions
|
||||||
extract_value( Doors.auto_duration, "DoorStayOpen", line, "" );
|
extract_value( Doors.auto_duration, "DoorStayOpen", line, "" );
|
||||||
@@ -8683,6 +8749,7 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
|
|||||||
extract_value( EIMCtrlType, "EIMCtrlType", line, "" );
|
extract_value( EIMCtrlType, "EIMCtrlType", line, "" );
|
||||||
clamp( EIMCtrlType, 0, 3 );
|
clamp( EIMCtrlType, 0, 3 );
|
||||||
LocHandleTimeTraxx = (extract_value("LocalBrakeTraxx", line) == "Yes");
|
LocHandleTimeTraxx = (extract_value("LocalBrakeTraxx", line) == "Yes");
|
||||||
|
EIMCtrlAdditionalZeros = (extract_value("EIMCtrlAddZeros", line) == "Yes");
|
||||||
|
|
||||||
extract_value( ScndS, "ScndS", line, "" ); // brak pozycji rownoleglej przy niskiej nastawie PSR
|
extract_value( ScndS, "ScndS", line, "" ); // brak pozycji rownoleglej przy niskiej nastawie PSR
|
||||||
|
|
||||||
@@ -8705,6 +8772,7 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
|
|||||||
(extract_value("SpeedCtrlType", line) == "Time") ?
|
(extract_value("SpeedCtrlType", line) == "Time") ?
|
||||||
true :
|
true :
|
||||||
false;
|
false;
|
||||||
|
extract_value(SpeedCtrlAutoTurnOffFlag, "SpeedCtrlATOF", line, "");
|
||||||
|
|
||||||
// converter
|
// converter
|
||||||
{
|
{
|
||||||
@@ -8735,6 +8803,14 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
|
|||||||
lookup->second :
|
lookup->second :
|
||||||
start_t::manual;
|
start_t::manual;
|
||||||
}
|
}
|
||||||
|
// pantograph compressor
|
||||||
|
{
|
||||||
|
auto lookup = starts.find( extract_value( "PantCompressorStart", line ) );
|
||||||
|
PantographCompressorStart =
|
||||||
|
lookup != starts.end() ?
|
||||||
|
lookup->second :
|
||||||
|
start_t::manual;
|
||||||
|
}
|
||||||
// fuel pump
|
// fuel pump
|
||||||
{
|
{
|
||||||
auto lookup = starts.find( extract_value( "FuelStart", line ) );
|
auto lookup = starts.find( extract_value( "FuelStart", line ) );
|
||||||
@@ -8961,6 +9037,7 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
|||||||
ImaxLo = 1;
|
ImaxLo = 1;
|
||||||
}
|
}
|
||||||
extract_value( EngineHeatingRPM, "HeatingRPM", Input, "" );
|
extract_value( EngineHeatingRPM, "HeatingRPM", Input, "" );
|
||||||
|
extract_value( dizel_AIM, "AIM", Input, "1.25" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TEngineType::ElectricInductionMotor: {
|
case TEngineType::ElectricInductionMotor: {
|
||||||
@@ -10048,6 +10125,13 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
|||||||
false );
|
false );
|
||||||
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||||
}
|
}
|
||||||
|
else if( Command == "DoorMode" ) {
|
||||||
|
Doors.remote_only = (
|
||||||
|
CValue1 == 1 ?
|
||||||
|
true :
|
||||||
|
false );
|
||||||
|
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||||
|
}
|
||||||
else if( Command == "DepartureSignal" ) {
|
else if( Command == "DepartureSignal" ) {
|
||||||
DepartureSignal = (
|
DepartureSignal = (
|
||||||
CValue1 == 1 ?
|
CValue1 == 1 ?
|
||||||
@@ -10064,12 +10148,10 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
|||||||
if ((CValue1 == 1))
|
if ((CValue1 == 1))
|
||||||
{
|
{
|
||||||
PantFrontUp = true;
|
PantFrontUp = true;
|
||||||
PantFrontStart = 0;
|
|
||||||
}
|
}
|
||||||
else if ((CValue1 == 0))
|
else if ((CValue1 == 0))
|
||||||
{
|
{
|
||||||
PantFrontUp = false;
|
PantFrontUp = false;
|
||||||
PantFrontStart = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -10079,24 +10161,20 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
|||||||
(TestFlag(Couplers[0].CouplingFlag, ctrain_controll) && (CValue2 == -1)))
|
(TestFlag(Couplers[0].CouplingFlag, ctrain_controll) && (CValue2 == -1)))
|
||||||
{
|
{
|
||||||
PantFrontUp = true;
|
PantFrontUp = true;
|
||||||
PantFrontStart = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PantRearUp = true;
|
PantRearUp = true;
|
||||||
PantRearStart = 0;
|
|
||||||
}
|
}
|
||||||
else if ((CValue1 == 0))
|
else if ((CValue1 == 0))
|
||||||
if ((TestFlag(Couplers[1].CouplingFlag, ctrain_controll) && (CValue2 == 1)) ||
|
if ((TestFlag(Couplers[1].CouplingFlag, ctrain_controll) && (CValue2 == 1)) ||
|
||||||
(TestFlag(Couplers[0].CouplingFlag, ctrain_controll) && (CValue2 == -1)))
|
(TestFlag(Couplers[0].CouplingFlag, ctrain_controll) && (CValue2 == -1)))
|
||||||
{
|
{
|
||||||
PantFrontUp = false;
|
PantFrontUp = false;
|
||||||
PantFrontStart = 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PantRearUp = false;
|
PantRearUp = false;
|
||||||
PantRearStart = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||||
@@ -10109,12 +10187,10 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
|||||||
if ((CValue1 == 1))
|
if ((CValue1 == 1))
|
||||||
{
|
{
|
||||||
PantRearUp = true;
|
PantRearUp = true;
|
||||||
PantRearStart = 0;
|
|
||||||
}
|
}
|
||||||
else if ((CValue1 == 0))
|
else if ((CValue1 == 0))
|
||||||
{
|
{
|
||||||
PantRearUp = false;
|
PantRearUp = false;
|
||||||
PantRearStart = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -10125,24 +10201,20 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
|||||||
(TestFlag(Couplers[0].CouplingFlag, ctrain_controll) && (CValue2 == -1)))
|
(TestFlag(Couplers[0].CouplingFlag, ctrain_controll) && (CValue2 == -1)))
|
||||||
{
|
{
|
||||||
PantRearUp = true;
|
PantRearUp = true;
|
||||||
PantRearStart = 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PantFrontUp = true;
|
PantFrontUp = true;
|
||||||
PantFrontStart = 0;
|
|
||||||
}
|
}
|
||||||
else if ((CValue1 == 0))
|
else if ((CValue1 == 0))
|
||||||
if ((TestFlag(Couplers[1].CouplingFlag, ctrain_controll) && (CValue2 == 1)) ||
|
if ((TestFlag(Couplers[1].CouplingFlag, ctrain_controll) && (CValue2 == 1)) ||
|
||||||
(TestFlag(Couplers[0].CouplingFlag, ctrain_controll) && (CValue2 == -1)))
|
(TestFlag(Couplers[0].CouplingFlag, ctrain_controll) && (CValue2 == -1)))
|
||||||
{
|
{
|
||||||
PantRearUp = false;
|
PantRearUp = false;
|
||||||
PantRearStart = 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PantFrontUp = false;
|
PantFrontUp = false;
|
||||||
PantFrontStart = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||||
|
|||||||
@@ -385,6 +385,11 @@ void TBrake::Releaser( int const state )
|
|||||||
BrakeStatus = (BrakeStatus & ~b_rls) | ( state * b_rls );
|
BrakeStatus = (BrakeStatus & ~b_rls) | ( state * b_rls );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TBrake::Releaser() const {
|
||||||
|
|
||||||
|
return ( ( BrakeStatus & b_rls ) == b_rls );
|
||||||
|
}
|
||||||
|
|
||||||
void TBrake::SetEPS( double const nEPS )
|
void TBrake::SetEPS( double const nEPS )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -1370,7 +1375,7 @@ double TLSt::GetPF( double const PP, double const dt, double const Vel )
|
|||||||
temp = 10000;
|
temp = 10000;
|
||||||
|
|
||||||
// powtarzacz — podwojny zawor zwrotny
|
// powtarzacz — podwojny zawor zwrotny
|
||||||
temp = Max0R(((CVP - BCP) * BVM + ASBP * int((BrakeStatus & b_asb) == b_asb)) / temp, LBP);
|
temp = Max0R(((CVP - BCP) * BVM + ASBP * int((BrakeStatus & b_asb_unbrake) == b_asb_unbrake)) / temp, LBP);
|
||||||
// luzowanie CH
|
// luzowanie CH
|
||||||
if ((BrakeCyl->P() > temp + 0.005) || (temp < 0.28))
|
if ((BrakeCyl->P() > temp + 0.005) || (temp < 0.28))
|
||||||
// dV:=PF(0,BrakeCyl->P(),0.0015*3*sizeBC)*dt
|
// dV:=PF(0,BrakeCyl->P(),0.0015*3*sizeBC)*dt
|
||||||
@@ -2773,6 +2778,8 @@ double TMHZ_K5P::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
|||||||
void TMHZ_K5P::Init(double Press)
|
void TMHZ_K5P::Init(double Press)
|
||||||
{
|
{
|
||||||
CP = Press;
|
CP = Press;
|
||||||
|
Time = true;
|
||||||
|
TimeEP = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TMHZ_K5P::SetReductor(double nAdj)
|
void TMHZ_K5P::SetReductor(double nAdj)
|
||||||
|
|||||||
@@ -203,6 +203,7 @@ class TBrake {
|
|||||||
virtual double GetCRP(); //cisnienie zbiornika sterujacego
|
virtual double GetCRP(); //cisnienie zbiornika sterujacego
|
||||||
bool SetBDF( int const nBDF ); //nastawiacz GPRM
|
bool SetBDF( int const nBDF ); //nastawiacz GPRM
|
||||||
void Releaser( int const state ); //odluzniacz
|
void Releaser( int const state ); //odluzniacz
|
||||||
|
bool Releaser() const;
|
||||||
virtual void SetEPS( double const nEPS ); //hamulec EP
|
virtual void SetEPS( double const nEPS ); //hamulec EP
|
||||||
virtual void SetRM( double const RMR ) {}; //ustalenie przelozenia rapida
|
virtual void SetRM( double const RMR ) {}; //ustalenie przelozenia rapida
|
||||||
virtual void SetRV( double const RVR) {}; //ustalenie przelozenia rapida
|
virtual void SetRV( double const RVR) {}; //ustalenie przelozenia rapida
|
||||||
|
|||||||
253
Train.cpp
253
Train.cpp
@@ -327,6 +327,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
|
|||||||
{ user_command::dooropenall, &TTrain::OnCommand_dooropenall },
|
{ user_command::dooropenall, &TTrain::OnCommand_dooropenall },
|
||||||
{ user_command::doorcloseall, &TTrain::OnCommand_doorcloseall },
|
{ user_command::doorcloseall, &TTrain::OnCommand_doorcloseall },
|
||||||
{ user_command::doorsteptoggle, &TTrain::OnCommand_doorsteptoggle },
|
{ user_command::doorsteptoggle, &TTrain::OnCommand_doorsteptoggle },
|
||||||
|
{ user_command::doormodetoggle, &TTrain::OnCommand_doormodetoggle },
|
||||||
{ user_command::carcouplingincrease, &TTrain::OnCommand_carcouplingincrease },
|
{ user_command::carcouplingincrease, &TTrain::OnCommand_carcouplingincrease },
|
||||||
{ user_command::carcouplingdisconnect, &TTrain::OnCommand_carcouplingdisconnect },
|
{ user_command::carcouplingdisconnect, &TTrain::OnCommand_carcouplingdisconnect },
|
||||||
{ user_command::departureannounce, &TTrain::OnCommand_departureannounce },
|
{ user_command::departureannounce, &TTrain::OnCommand_departureannounce },
|
||||||
@@ -388,8 +389,11 @@ TTrain::TTrain() {
|
|||||||
bHeat[ i ] = false;
|
bHeat[ i ] = false;
|
||||||
}
|
}
|
||||||
for( int i = 0; i < 9; ++i )
|
for( int i = 0; i < 9; ++i )
|
||||||
for( int j = 0; j < 10; ++j )
|
for (int j = 0; j < 10; ++j)
|
||||||
fEIMParams[ i ][ j ] = 0.0;
|
{
|
||||||
|
fEIMParams[i][j] = 0.0;
|
||||||
|
fDieselParams[i][j] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
for( int i = 0; i < 20; ++i )
|
for( int i = 0; i < 20; ++i )
|
||||||
for( int j = 0; j < 3; ++j )
|
for( int j = 0; j < 3; ++j )
|
||||||
@@ -454,10 +458,10 @@ dictionary_source *TTrain::GetTrainState() {
|
|||||||
// reverser
|
// reverser
|
||||||
dict->insert( "direction", mover->ActiveDir );
|
dict->insert( "direction", mover->ActiveDir );
|
||||||
// throttle
|
// throttle
|
||||||
dict->insert( "mainctrl_pos", mover->MainCtrlPos );
|
dict->insert( "mainctrl_pos", mvControlled->MainCtrlPos );
|
||||||
dict->insert( "main_ctrl_actual_pos", mover->MainCtrlActualPos );
|
dict->insert( "main_ctrl_actual_pos", mvControlled->MainCtrlActualPos );
|
||||||
dict->insert( "scndctrl_pos", mover->ScndCtrlPos );
|
dict->insert( "scndctrl_pos", mvControlled->ScndCtrlPos );
|
||||||
dict->insert( "scnd_ctrl_actual_pos", mover->ScndCtrlActualPos );
|
dict->insert( "scnd_ctrl_actual_pos", mvControlled->ScndCtrlActualPos );
|
||||||
dict->insert( "new_speed", mover->NewSpeed);
|
dict->insert( "new_speed", mover->NewSpeed);
|
||||||
// brakes
|
// brakes
|
||||||
dict->insert( "manual_brake", ( mvOccupied->ManualBrakePos > 0 ) );
|
dict->insert( "manual_brake", ( mvOccupied->ManualBrakePos > 0 ) );
|
||||||
@@ -496,6 +500,7 @@ dictionary_source *TTrain::GetTrainState() {
|
|||||||
// induction motor state data
|
// induction motor state data
|
||||||
char const *TXTT[ 10 ] = { "fd", "fdt", "fdb", "pd", "pdt", "pdb", "itothv", "1", "2", "3" };
|
char const *TXTT[ 10 ] = { "fd", "fdt", "fdb", "pd", "pdt", "pdb", "itothv", "1", "2", "3" };
|
||||||
char const *TXTC[ 10 ] = { "fr", "frt", "frb", "pr", "prt", "prb", "im", "vm", "ihv", "uhv" };
|
char const *TXTC[ 10 ] = { "fr", "frt", "frb", "pr", "prt", "prb", "im", "vm", "ihv", "uhv" };
|
||||||
|
char const *TXTD[ 10 ] = { "enrot", "nrot", "fill_des", "fill_real", "clutch_des", "clutch_real", "water_temp", "oil_press", "res1", "res2" };
|
||||||
char const *TXTP[ 3 ] = { "bc", "bp", "sp" };
|
char const *TXTP[ 3 ] = { "bc", "bp", "sp" };
|
||||||
for( int j = 0; j < 10; ++j )
|
for( int j = 0; j < 10; ++j )
|
||||||
dict->insert( ( "eimp_t_" + std::string( TXTT[ j ] ) ), fEIMParams[ 0 ][ j ] );
|
dict->insert( ( "eimp_t_" + std::string( TXTT[ j ] ) ), fEIMParams[ 0 ][ j ] );
|
||||||
@@ -503,6 +508,9 @@ dictionary_source *TTrain::GetTrainState() {
|
|||||||
for( int j = 0; j < 10; ++j )
|
for( int j = 0; j < 10; ++j )
|
||||||
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_" + std::string( TXTC[ j ] ) ), fEIMParams[ i + 1 ][ j ] );
|
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_" + std::string( TXTC[ j ] ) ), fEIMParams[ i + 1 ][ j ] );
|
||||||
|
|
||||||
|
for (int j = 0; j < 10; ++j)
|
||||||
|
dict->insert(("diesel_param_" + std::to_string(i + 1) + "_" + std::string(TXTD[j])), fDieselParams[i + 1][j]);
|
||||||
|
|
||||||
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_ms" ), bMains[ i ] );
|
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_ms" ), bMains[ i ] );
|
||||||
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_cv" ), fCntVol[ i ] );
|
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_cv" ), fCntVol[ i ] );
|
||||||
dict->insert( ( "eimp_u" + std::to_string( i + 1 ) + "_pf" ), bPants[ i ][ 0 ] );
|
dict->insert( ( "eimp_u" + std::to_string( i + 1 ) + "_pf" ), bPants[ i ][ 0 ] );
|
||||||
@@ -648,7 +656,8 @@ void TTrain::zero_charging_train_brake() {
|
|||||||
&& ( DynamicObject->Controller != AIdriver )
|
&& ( DynamicObject->Controller != AIdriver )
|
||||||
&& ( Global.iFeedbackMode < 3 )
|
&& ( Global.iFeedbackMode < 3 )
|
||||||
&& ( ( mvOccupied->BrakeHandle == TBrakeHandle::FVel6 )
|
&& ( ( mvOccupied->BrakeHandle == TBrakeHandle::FVel6 )
|
||||||
|| ( mvOccupied->BrakeHandle == TBrakeHandle::MHZ_EN57 ) ) ) {
|
|| (mvOccupied->BrakeHandle == TBrakeHandle::MHZ_EN57)
|
||||||
|
|| (mvOccupied->BrakeHandle == TBrakeHandle::MHZ_K8P)) ) {
|
||||||
// Odskakiwanie hamulce EP
|
// Odskakiwanie hamulce EP
|
||||||
set_train_brake( 0 );
|
set_train_brake( 0 );
|
||||||
}
|
}
|
||||||
@@ -781,7 +790,7 @@ void TTrain::OnCommand_mastercontrollerincrease( TTrain *Train, command_data con
|
|||||||
if( Command.action != GLFW_RELEASE ) {
|
if( Command.action != GLFW_RELEASE ) {
|
||||||
// on press or hold
|
// on press or hold
|
||||||
if( ( Train->ggJointCtrl.SubModel != nullptr )
|
if( ( Train->ggJointCtrl.SubModel != nullptr )
|
||||||
&& ( Train->mvControlled->LocalBrakePosA > 0.0 ) ) {
|
&& ( Train->mvOccupied->LocalBrakePosA > 0.0 ) ) {
|
||||||
OnCommand_independentbrakedecrease( Train, Command );
|
OnCommand_independentbrakedecrease( Train, Command );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -801,7 +810,7 @@ void TTrain::OnCommand_mastercontrollerincreasefast( TTrain *Train, command_data
|
|||||||
if( Command.action != GLFW_RELEASE ) {
|
if( Command.action != GLFW_RELEASE ) {
|
||||||
// on press or hold
|
// on press or hold
|
||||||
if( ( Train->ggJointCtrl.SubModel != nullptr )
|
if( ( Train->ggJointCtrl.SubModel != nullptr )
|
||||||
&& ( Train->mvControlled->LocalBrakePosA > 0.0 ) ) {
|
&& ( Train->mvOccupied->LocalBrakePosA > 0.0 ) ) {
|
||||||
OnCommand_independentbrakedecreasefast( Train, Command );
|
OnCommand_independentbrakedecreasefast( Train, Command );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1712,10 +1721,11 @@ void TTrain::OnCommand_alerteracknowledge( TTrain *Train, command_data const &Co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command )
|
// TODO: replace battery with a two-state device, update switch code accordingly
|
||||||
{
|
void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command ) {
|
||||||
if( Command.action == GLFW_PRESS ) {
|
|
||||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
if( Command.action != GLFW_REPEAT ) {
|
||||||
|
// keep the switch from flipping back and forth if key is held down
|
||||||
if( false == Train->mvOccupied->Battery ) {
|
if( false == Train->mvOccupied->Battery ) {
|
||||||
// turn on
|
// turn on
|
||||||
OnCommand_batteryenable( Train, Command );
|
OnCommand_batteryenable( Train, Command );
|
||||||
@@ -1729,16 +1739,13 @@ void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command
|
|||||||
|
|
||||||
void TTrain::OnCommand_batteryenable( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_batteryenable( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
if( true == Train->mvOccupied->Battery ) { return; } // already on
|
|
||||||
|
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
// ignore repeats
|
// visual feedback
|
||||||
// wyłącznik jest też w SN61, ewentualnie załączać prąd na stałe z poziomu FIZ
|
Train->ggBatteryButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||||
|
|
||||||
|
if( true == Train->mvOccupied->Battery ) { return; } // already on
|
||||||
|
|
||||||
if( Train->mvOccupied->BatterySwitch( true ) ) {
|
if( Train->mvOccupied->BatterySwitch( true ) ) {
|
||||||
// bateria potrzebna np. do zapalenia świateł
|
|
||||||
if( Train->ggBatteryButton.SubModel ) {
|
|
||||||
Train->ggBatteryButton.UpdateValue( 1.0, Train->dsbSwitch );
|
|
||||||
}
|
|
||||||
// side-effects
|
// side-effects
|
||||||
if( Train->mvOccupied->LightsPosNo > 0 ) {
|
if( Train->mvOccupied->LightsPosNo > 0 ) {
|
||||||
Train->SetLights();
|
Train->SetLights();
|
||||||
@@ -1750,19 +1757,23 @@ void TTrain::OnCommand_batteryenable( TTrain *Train, command_data const &Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
|
if( Train->ggBatteryButton.type() == TGaugeType::push ) {
|
||||||
|
// return the switch to neutral position
|
||||||
|
Train->ggBatteryButton.UpdateValue( 0.5f );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TTrain::OnCommand_batterydisable( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_batterydisable( TTrain *Train, command_data const &Command ) {
|
||||||
|
// TBD, TODO: ewentualnie zablokować z FIZ, np. w samochodach się nie odłącza akumulatora
|
||||||
if( false == Train->mvOccupied->Battery ) { return; } // already off
|
|
||||||
|
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
// ignore repeats
|
// visual feedback
|
||||||
|
Train->ggBatteryButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
|
|
||||||
|
if( false == Train->mvOccupied->Battery ) { return; } // already off
|
||||||
|
|
||||||
if( Train->mvOccupied->BatterySwitch( false ) ) {
|
if( Train->mvOccupied->BatterySwitch( false ) ) {
|
||||||
// ewentualnie zablokować z FIZ, np. w samochodach się nie odłącza akumulatora
|
|
||||||
if( Train->ggBatteryButton.SubModel ) {
|
|
||||||
Train->ggBatteryButton.UpdateValue( 0.0, Train->dsbSwitch );
|
|
||||||
}
|
|
||||||
// side-effects
|
// side-effects
|
||||||
if( false == Train->mvControlled->ConverterFlag ) {
|
if( false == Train->mvControlled->ConverterFlag ) {
|
||||||
// if there's no (low voltage) power source left, drop pantographs
|
// if there's no (low voltage) power source left, drop pantographs
|
||||||
@@ -1771,6 +1782,12 @@ void TTrain::OnCommand_batterydisable( TTrain *Train, command_data const &Comman
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
|
if( Train->ggBatteryButton.type() == TGaugeType::push ) {
|
||||||
|
// return the switch to neutral position
|
||||||
|
Train->ggBatteryButton.UpdateValue( 0.5f );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const &cmd )
|
void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const &cmd )
|
||||||
@@ -4129,7 +4146,7 @@ void TTrain::OnCommand_heatingtoggle( TTrain *Train, command_data const &Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
// ignore repeats so the switch doesn't flip back and forth if key is held down
|
||||||
if( false == Train->mvControlled->HeatingAllow ) {
|
if( false == Train->mvControlled->HeatingAllow ) {
|
||||||
// turn on
|
// turn on
|
||||||
OnCommand_heatingenable( Train, Command );
|
OnCommand_heatingenable( Train, Command );
|
||||||
@@ -4139,6 +4156,14 @@ void TTrain::OnCommand_heatingtoggle( TTrain *Train, command_data const &Command
|
|||||||
OnCommand_heatingdisable( Train, Command );
|
OnCommand_heatingdisable( Train, Command );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
|
|
||||||
|
if( Train->ggTrainHeatingButton.type() == TGaugeType::push ) {
|
||||||
|
// impulse switch
|
||||||
|
// visual feedback
|
||||||
|
Train->ggTrainHeatingButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TTrain::OnCommand_heatingenable( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_heatingenable( TTrain *Train, command_data const &Command ) {
|
||||||
@@ -4157,7 +4182,11 @@ void TTrain::OnCommand_heatingdisable( TTrain *Train, command_data const &Comman
|
|||||||
|
|
||||||
Train->mvControlled->HeatingAllow = false;
|
Train->mvControlled->HeatingAllow = false;
|
||||||
// visual feedback
|
// visual feedback
|
||||||
Train->ggTrainHeatingButton.UpdateValue( 0.0, Train->dsbSwitch );
|
Train->ggTrainHeatingButton.UpdateValue(
|
||||||
|
( Train->ggTrainHeatingButton.type() == TGaugeType::push ?
|
||||||
|
1.0 :
|
||||||
|
0.0 ),
|
||||||
|
Train->dsbSwitch );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4288,37 +4317,73 @@ void TTrain::OnCommand_doortoggleleft( TTrain *Train, command_data const &Comman
|
|||||||
|
|
||||||
void TTrain::OnCommand_doorpermitleft( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_doorpermitleft( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
|
if( Command.action == GLFW_REPEAT ) { return; }
|
||||||
|
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
|
|
||||||
Train->mvOccupied->PermitDoors(
|
auto const side { (
|
||||||
( Train->mvOccupied->ActiveCab == 1 ?
|
Train->mvOccupied->ActiveCab == 1 ?
|
||||||
side::left :
|
side::left :
|
||||||
side::right ) );
|
side::right ) };
|
||||||
|
|
||||||
// visual feedback
|
if( Train->ggDoorLeftPermitButton.type() == TGaugeType::push ) {
|
||||||
Train->ggDoorLeftPermitButton.UpdateValue( 1.0, Train->dsbSwitch );
|
// impulse switch
|
||||||
|
Train->mvOccupied->PermitDoors( side );
|
||||||
|
// visual feedback
|
||||||
|
Train->ggDoorLeftPermitButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// two-state switch
|
||||||
|
auto const newstate { !( Train->mvOccupied->Doors.instances[ side ].open_permit ) };
|
||||||
|
|
||||||
|
Train->mvOccupied->PermitDoors( side, newstate );
|
||||||
|
// visual feedback
|
||||||
|
Train->ggDoorLeftPermitButton.UpdateValue( ( newstate ? 1.0 : 0.0 ), Train->dsbSwitch );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( Command.action == GLFW_RELEASE ) {
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
// visual feedback
|
|
||||||
Train->ggDoorLeftPermitButton.UpdateValue( 0.0, Train->dsbSwitch );
|
if( Train->ggDoorLeftPermitButton.type() == TGaugeType::push ) {
|
||||||
|
// impulse switch
|
||||||
|
// visual feedback
|
||||||
|
Train->ggDoorLeftPermitButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TTrain::OnCommand_doorpermitright( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_doorpermitright( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
|
if( Command.action == GLFW_REPEAT ) { return; }
|
||||||
|
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
|
|
||||||
Train->mvOccupied->PermitDoors(
|
auto const side { (
|
||||||
( Train->mvOccupied->ActiveCab == 1 ?
|
Train->mvOccupied->ActiveCab == 1 ?
|
||||||
side::right :
|
side::right :
|
||||||
side::left ) );
|
side::left ) };
|
||||||
|
|
||||||
// visual feedback
|
if( Train->ggDoorRightPermitButton.type() == TGaugeType::push ) {
|
||||||
Train->ggDoorRightPermitButton.UpdateValue( 1.0, Train->dsbSwitch );
|
// impulse switch
|
||||||
|
Train->mvOccupied->PermitDoors( side );
|
||||||
|
// visual feedback
|
||||||
|
Train->ggDoorRightPermitButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// two-state switch
|
||||||
|
auto const newstate { !( Train->mvOccupied->Doors.instances[ side ].open_permit ) };
|
||||||
|
|
||||||
|
Train->mvOccupied->PermitDoors( side, newstate );
|
||||||
|
// visual feedback
|
||||||
|
Train->ggDoorRightPermitButton.UpdateValue( ( newstate ? 1.0 : 0.0 ), Train->dsbSwitch );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( Command.action == GLFW_RELEASE ) {
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
// visual feedback
|
|
||||||
Train->ggDoorRightPermitButton.UpdateValue( 0.0, Train->dsbSwitch );
|
if( Train->ggDoorRightPermitButton.type() == TGaugeType::push ) {
|
||||||
|
// impulse switch
|
||||||
|
// visual feedback
|
||||||
|
Train->ggDoorRightPermitButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4688,6 +4753,13 @@ void TTrain::OnCommand_doorsteptoggle( TTrain *Train, command_data const &Comman
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TTrain::OnCommand_doormodetoggle( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
|
if( Command.action == GLFW_PRESS ) {
|
||||||
|
Train->mvOccupied->ChangeDoorControlMode( false == Train->mvOccupied->Doors.remote_only );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TTrain::OnCommand_carcouplingincrease( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_carcouplingincrease( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
if( ( true == FreeFlyModeFlag )
|
if( ( true == FreeFlyModeFlag )
|
||||||
@@ -5171,7 +5243,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool kier = (DynamicObject->DirectionGet() * mvOccupied->ActiveCab > 0);
|
bool kier = (DynamicObject->DirectionGet() * mvOccupied->ActiveCab > 0);
|
||||||
TDynamicObject *p = DynamicObject->GetFirstDynamic(mvOccupied->ActiveCab < 0 ? 1 : 0, 4);
|
TDynamicObject *p = DynamicObject->GetFirstDynamic(mvOccupied->ActiveCab < 0 ? end::rear : end::front, 4);
|
||||||
int in = 0;
|
int in = 0;
|
||||||
fEIMParams[0][6] = 0;
|
fEIMParams[0][6] = 0;
|
||||||
iCarNo = 0;
|
iCarNo = 0;
|
||||||
@@ -5240,6 +5312,27 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
in++;
|
in++;
|
||||||
iPowerNo = in;
|
iPowerNo = in;
|
||||||
}
|
}
|
||||||
|
if ((in < 8) && (p->MoverParameters->EngineType==TEngineType::DieselEngine))
|
||||||
|
{
|
||||||
|
fDieselParams[1 + in][0] = p->MoverParameters->enrot*60;
|
||||||
|
fDieselParams[1 + in][1] = p->MoverParameters->nrot;
|
||||||
|
fDieselParams[1 + in][2] = p->MoverParameters->RList[p->MoverParameters->MainCtrlPos].R;
|
||||||
|
fDieselParams[1 + in][3] = p->MoverParameters->dizel_fill;
|
||||||
|
fDieselParams[1 + in][4] = p->MoverParameters->RList[p->MoverParameters->MainCtrlPos].Mn;
|
||||||
|
fDieselParams[1 + in][5] = p->MoverParameters->dizel_engage;
|
||||||
|
fDieselParams[1 + in][6] = p->MoverParameters->dizel_heat.Twy;
|
||||||
|
fDieselParams[1 + in][7] = p->MoverParameters->OilPump.pressure;
|
||||||
|
//fDieselParams[1 + in][8] = p->MoverParameters->
|
||||||
|
//fDieselParams[1 + in][9] = p->MoverParameters->
|
||||||
|
bMains[in] = p->MoverParameters->Mains;
|
||||||
|
fCntVol[in] = p->MoverParameters->BatteryVoltage;
|
||||||
|
bFuse[in] = p->MoverParameters->FuseFlag;
|
||||||
|
bBatt[in] = p->MoverParameters->Battery;
|
||||||
|
bConv[in] = p->MoverParameters->ConverterFlag;
|
||||||
|
bHeat[in] = p->MoverParameters->Heating;
|
||||||
|
in++;
|
||||||
|
iPowerNo = in;
|
||||||
|
}
|
||||||
// p = p->NextC(4); //prev
|
// p = p->NextC(4); //prev
|
||||||
if ((kier ? p->NextC(128) : p->PrevC(128)) != (kier ? p->NextC(4) : p->PrevC(4)))
|
if ((kier ? p->NextC(128) : p->PrevC(128)) != (kier ? p->NextC(4) : p->PrevC(4)))
|
||||||
iUnitNo++;
|
iUnitNo++;
|
||||||
@@ -5282,16 +5375,11 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
|
|
||||||
for (int i = in; i < 8; i++)
|
for (int i = in; i < 8; i++)
|
||||||
{
|
{
|
||||||
fEIMParams[1 + i][0] = 0;
|
for (int j = 0; j <= 9; j++)
|
||||||
fEIMParams[1 + i][1] = 0;
|
{
|
||||||
fEIMParams[1 + i][2] = 0;
|
fEIMParams[1 + i][j] = 0;
|
||||||
fEIMParams[1 + i][3] = 0;
|
fDieselParams[1 + i][j] = 0;
|
||||||
fEIMParams[1 + i][4] = 0;
|
}
|
||||||
fEIMParams[1 + i][5] = 0;
|
|
||||||
fEIMParams[1 + i][6] = 0;
|
|
||||||
fEIMParams[1 + i][7] = 0;
|
|
||||||
fEIMParams[1 + i][8] = 0;
|
|
||||||
fEIMParams[1 + i][9] = 0;
|
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (Global.iFeedbackMode == 4) {
|
if (Global.iFeedbackMode == 4) {
|
||||||
@@ -6493,7 +6581,7 @@ void TTrain::update_sounds_radio() {
|
|||||||
auto const volume {
|
auto const volume {
|
||||||
( true == radioenabled )
|
( true == radioenabled )
|
||||||
&& ( message.first == iRadioChannel ) ?
|
&& ( message.first == iRadioChannel ) ?
|
||||||
1.0 :
|
Global.RadioVolume :
|
||||||
0.0 };
|
0.0 };
|
||||||
message.second->gain( volume );
|
message.second->gain( volume );
|
||||||
}
|
}
|
||||||
@@ -7068,28 +7156,11 @@ void TTrain::DynamicSet(TDynamicObject *d)
|
|||||||
// jeździć dobrze
|
// 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...
|
||||||
DynamicObject = d; // jedyne miejsce zmiany
|
DynamicObject = d; // jedyne miejsce zmiany
|
||||||
mvOccupied = mvControlled = d ? DynamicObject->MoverParameters : NULL; // albo silnikowy w EZT
|
mvOccupied = mvControlled = ( d ? DynamicObject->MoverParameters : nullptr ); // albo silnikowy w EZT
|
||||||
if (!DynamicObject)
|
|
||||||
return;
|
|
||||||
// TODO: leverage code already present in TDynamicObject::ControlledFind()
|
|
||||||
if( ( d->MoverParameters->TrainType == dt_EZT )
|
|
||||||
|| ( d->MoverParameters->TrainType == dt_DMU ) ) {
|
|
||||||
|
|
||||||
if( ( d->NextConnected() != nullptr )
|
if( DynamicObject == nullptr ) { return; }
|
||||||
&& ( true == TestFlag( d->MoverParameters->Couplers[ end::rear ].AllowedFlag, coupling::permanent ) ) ) {
|
|
||||||
if( ( mvControlled->Power < 1.0 ) && ( mvControlled->Couplers[ 1 ].Connected->Power > 1.0 ) ) {
|
mvControlled = DynamicObject->ControlledFind()->MoverParameters;
|
||||||
// my nie mamy mocy, ale ten drugi ma
|
|
||||||
mvControlled = DynamicObject->NextConnected()->MoverParameters; // będziemy sterować tym z mocą
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( ( d->PrevConnected() != nullptr )
|
|
||||||
&& ( true == TestFlag( d->MoverParameters->Couplers[ end::front ].AllowedFlag, coupling::permanent ) ) ) {
|
|
||||||
if( ( mvControlled->Power < 1.0 ) && ( mvControlled->Couplers[ 0 ].Connected->Power > 1.0 ) ) {
|
|
||||||
// my nie mamy mocy, ale ten drugi ma
|
|
||||||
mvControlled = DynamicObject->PrevConnected()->MoverParameters; // będziemy sterować tym z mocą
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 ?
|
||||||
@@ -7413,9 +7484,10 @@ void TTrain::clear_cab_controls()
|
|||||||
void TTrain::set_cab_controls( int const Cab ) {
|
void TTrain::set_cab_controls( int const Cab ) {
|
||||||
// switches
|
// switches
|
||||||
// battery
|
// battery
|
||||||
if( true == mvOccupied->Battery ) {
|
ggBatteryButton.PutValue(
|
||||||
ggBatteryButton.PutValue( 1.f );
|
( ggBatteryButton.type() == TGaugeType::push ? 0.5f :
|
||||||
}
|
mvOccupied->Battery ? 1.f :
|
||||||
|
0.f ) );
|
||||||
// motor connectors
|
// motor connectors
|
||||||
ggStLinOffButton.PutValue(
|
ggStLinOffButton.PutValue(
|
||||||
( mvControlled->StLinSwitchOff ?
|
( mvControlled->StLinSwitchOff ?
|
||||||
@@ -7578,7 +7650,12 @@ void TTrain::set_cab_controls( int const Cab ) {
|
|||||||
1.f :
|
1.f :
|
||||||
0.f ) );
|
0.f ) );
|
||||||
// doors
|
// doors
|
||||||
// NOTE: for the time being permit switches are presumed to be impulse switches
|
if( ggDoorLeftPermitButton.type() != TGaugeType::push ) {
|
||||||
|
ggDoorLeftPermitButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::left : side::right ) ].open_permit ? 1.f : 0.f );
|
||||||
|
}
|
||||||
|
if( ggDoorRightPermitButton.type() != TGaugeType::push ) {
|
||||||
|
ggDoorRightPermitButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::right : side::left ) ].open_permit ? 1.f : 0.f );
|
||||||
|
}
|
||||||
ggDoorPermitPresetButton.PutValue( mvOccupied->Doors.permit_preset );
|
ggDoorPermitPresetButton.PutValue( mvOccupied->Doors.permit_preset );
|
||||||
ggDoorLeftButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::left : side::right ) ].is_closed ? 0.f : 1.f );
|
ggDoorLeftButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::left : side::right ) ].is_closed ? 0.f : 1.f );
|
||||||
ggDoorRightButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::right : side::left ) ].is_closed ? 0.f : 1.f );
|
ggDoorRightButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::right : side::left ) ].is_closed ? 0.f : 1.f );
|
||||||
@@ -7588,8 +7665,11 @@ void TTrain::set_cab_controls( int const Cab ) {
|
|||||||
1.f :
|
1.f :
|
||||||
0.f );
|
0.f );
|
||||||
// heating
|
// heating
|
||||||
if( true == mvControlled->Heating ) {
|
if( ggTrainHeatingButton.type() != TGaugeType::push ) {
|
||||||
ggTrainHeatingButton.PutValue( 1.f );
|
ggTrainHeatingButton.PutValue(
|
||||||
|
mvControlled->Heating ?
|
||||||
|
1.f :
|
||||||
|
0.f );
|
||||||
}
|
}
|
||||||
// brake acting time
|
// brake acting time
|
||||||
if( ggBrakeProfileCtrl.SubModel != nullptr ) {
|
if( ggBrakeProfileCtrl.SubModel != nullptr ) {
|
||||||
@@ -7807,8 +7887,8 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
|||||||
}
|
}
|
||||||
// TODO: move viable dedicated lights to the automatic light array
|
// TODO: move viable dedicated lights to the automatic light array
|
||||||
std::unordered_map<std::string, bool *> const autolights = {
|
std::unordered_map<std::string, bool *> const autolights = {
|
||||||
{ "i-doorpermit_left:", &mvOccupied->Doors.instances[side::left].open_permit },
|
{ "i-doorpermit_left:", &mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::left : side::right ) ].open_permit },
|
||||||
{ "i-doorpermit_right:", &mvOccupied->Doors.instances[ side::right ].open_permit },
|
{ "i-doorpermit_right:", &mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::right : side::left ) ].open_permit },
|
||||||
{ "i-doorstep:", &mvOccupied->Doors.step_enabled }
|
{ "i-doorstep:", &mvOccupied->Doors.step_enabled }
|
||||||
};
|
};
|
||||||
{
|
{
|
||||||
@@ -7978,6 +8058,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
}
|
}
|
||||||
// TODO: move viable dedicated gauges to the automatic array
|
// TODO: move viable dedicated gauges to the automatic array
|
||||||
std::unordered_map<std::string, bool *> const autoboolgauges = {
|
std::unordered_map<std::string, bool *> const autoboolgauges = {
|
||||||
|
{ "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 }
|
||||||
};
|
};
|
||||||
|
|||||||
2
Train.h
2
Train.h
@@ -330,6 +330,7 @@ class TTrain
|
|||||||
static void OnCommand_dooropenall( TTrain *Train, command_data const &Command );
|
static void OnCommand_dooropenall( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_doorcloseall( TTrain *Train, command_data const &Command );
|
static void OnCommand_doorcloseall( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_doorsteptoggle( TTrain *Train, command_data const &Command );
|
static void OnCommand_doorsteptoggle( TTrain *Train, command_data const &Command );
|
||||||
|
static void OnCommand_doormodetoggle( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_carcouplingincrease( TTrain *Train, command_data const &Command );
|
static void OnCommand_carcouplingincrease( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_carcouplingdisconnect( TTrain *Train, command_data const &Command );
|
static void OnCommand_carcouplingdisconnect( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_departureannounce( TTrain *Train, command_data const &Command );
|
static void OnCommand_departureannounce( TTrain *Train, command_data const &Command );
|
||||||
@@ -675,6 +676,7 @@ private:
|
|||||||
float fPress[20][3]; // cisnienia dla wszystkich czlonow
|
float fPress[20][3]; // cisnienia dla wszystkich czlonow
|
||||||
static std::vector<std::string> const fPress_labels;
|
static std::vector<std::string> const fPress_labels;
|
||||||
float fEIMParams[9][10]; // parametry dla silnikow asynchronicznych
|
float fEIMParams[9][10]; // parametry dla silnikow asynchronicznych
|
||||||
|
float fDieselParams[9][10]; // parametry dla silnikow asynchronicznych
|
||||||
int RadioChannel() const { return iRadioChannel; };
|
int RadioChannel() const { return iRadioChannel; };
|
||||||
// plays provided sound from position of the radio
|
// plays provided sound from position of the radio
|
||||||
void radio_message( sound_source *Message, int const Channel );
|
void radio_message( sound_source *Message, int const Channel );
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ commanddescription_sequence Commands_descriptions = {
|
|||||||
{ "doorcloseright", command_target::vehicle, command_mode::oneoff },
|
{ "doorcloseright", command_target::vehicle, command_mode::oneoff },
|
||||||
{ "doorcloseall", command_target::vehicle, command_mode::oneoff },
|
{ "doorcloseall", command_target::vehicle, command_mode::oneoff },
|
||||||
{ "doorsteptoggle", command_target::vehicle, command_mode::oneoff },
|
{ "doorsteptoggle", command_target::vehicle, command_mode::oneoff },
|
||||||
|
{ "doormodetoggle", command_target::vehicle, command_mode::oneoff },
|
||||||
{ "departureannounce", command_target::vehicle, command_mode::oneoff },
|
{ "departureannounce", command_target::vehicle, command_mode::oneoff },
|
||||||
{ "doorlocktoggle", command_target::vehicle, command_mode::oneoff },
|
{ "doorlocktoggle", command_target::vehicle, command_mode::oneoff },
|
||||||
{ "pantographcompressorvalvetoggle", command_target::vehicle, command_mode::oneoff },
|
{ "pantographcompressorvalvetoggle", command_target::vehicle, command_mode::oneoff },
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ enum class user_command {
|
|||||||
doorcloseright,
|
doorcloseright,
|
||||||
doorcloseall,
|
doorcloseall,
|
||||||
doorsteptoggle,
|
doorsteptoggle,
|
||||||
|
doormodetoggle,
|
||||||
departureannounce,
|
departureannounce,
|
||||||
doorlocktoggle,
|
doorlocktoggle,
|
||||||
pantographcompressorvalvetoggle,
|
pantographcompressorvalvetoggle,
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ driverkeyboard_input::default_bindings() {
|
|||||||
// doorcloseright,
|
// doorcloseright,
|
||||||
{ user_command::doorcloseall, GLFW_KEY_SLASH | keymodifier::control },
|
{ user_command::doorcloseall, GLFW_KEY_SLASH | keymodifier::control },
|
||||||
// doorsteptoggle,
|
// doorsteptoggle,
|
||||||
|
{ user_command::doormodetoggle, GLFW_KEY_SLASH | keymodifier::shift | keymodifier::control },
|
||||||
{ user_command::departureannounce, GLFW_KEY_SLASH },
|
{ user_command::departureannounce, GLFW_KEY_SLASH },
|
||||||
{ user_command::doorlocktoggle, GLFW_KEY_S | keymodifier::control },
|
{ user_command::doorlocktoggle, GLFW_KEY_S | keymodifier::control },
|
||||||
{ user_command::pantographcompressorvalvetoggle, GLFW_KEY_V | keymodifier::control },
|
{ user_command::pantographcompressorvalvetoggle, GLFW_KEY_V | keymodifier::control },
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "uilayer.h"
|
#include "uilayer.h"
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
|
|
||||||
auto const EU07_CONTROLLER_MOUSESLIDERSIZE{ 0.65 };
|
auto const EU07_CONTROLLER_MOUSESLIDERSIZE{ 0.6 };
|
||||||
|
|
||||||
void
|
void
|
||||||
mouse_slider::bind( user_command const &Command ) {
|
mouse_slider::bind( user_command const &Command ) {
|
||||||
@@ -634,6 +634,9 @@ drivermouse_input::default_bindings() {
|
|||||||
{ "doorstep_sw:", {
|
{ "doorstep_sw:", {
|
||||||
user_command::doorsteptoggle,
|
user_command::doorsteptoggle,
|
||||||
user_command::none } },
|
user_command::none } },
|
||||||
|
{ "doormode_sw:", {
|
||||||
|
user_command::doormodetoggle,
|
||||||
|
user_command::none } },
|
||||||
{ "departure_signal_bt:", {
|
{ "departure_signal_bt:", {
|
||||||
user_command::departureannounce,
|
user_command::departureannounce,
|
||||||
user_command::none } },
|
user_command::none } },
|
||||||
|
|||||||
@@ -229,6 +229,7 @@ timetable_panel::update() {
|
|||||||
if( false == is_open ) { return; }
|
if( false == is_open ) { return; }
|
||||||
|
|
||||||
text_lines.clear();
|
text_lines.clear();
|
||||||
|
m_tablelines.clear();
|
||||||
|
|
||||||
auto const *train { simulation::Train };
|
auto const *train { simulation::Train };
|
||||||
auto const *controlled { ( train ? train->Dynamic() : nullptr ) };
|
auto const *controlled { ( train ? train->Dynamic() : nullptr ) };
|
||||||
@@ -239,7 +240,7 @@ timetable_panel::update() {
|
|||||||
std::snprintf(
|
std::snprintf(
|
||||||
m_buffer.data(), m_buffer.size(),
|
m_buffer.data(), m_buffer.size(),
|
||||||
locale::strings[ locale::string::driver_timetable_header ].c_str(),
|
locale::strings[ locale::string::driver_timetable_header ].c_str(),
|
||||||
40, 40,
|
37, 37,
|
||||||
locale::strings[ locale::string::driver_timetable_name ].c_str(),
|
locale::strings[ locale::string::driver_timetable_name ].c_str(),
|
||||||
time.wHour,
|
time.wHour,
|
||||||
time.wMinute,
|
time.wMinute,
|
||||||
@@ -274,7 +275,7 @@ timetable_panel::update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{ // next station
|
{ // next station
|
||||||
auto const nextstation = Bezogonkow( owner->NextStop(), true );
|
auto const nextstation = owner->NextStop();
|
||||||
if( false == nextstation.empty() ) {
|
if( false == nextstation.empty() ) {
|
||||||
// jeśli jest podana relacja, to dodajemy punkt następnego zatrzymania
|
// jeśli jest podana relacja, to dodajemy punkt następnego zatrzymania
|
||||||
auto textline = " -> " + nextstation;
|
auto textline = " -> " + nextstation;
|
||||||
@@ -317,67 +318,126 @@ timetable_panel::update() {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
auto const loadingcolor { glm::vec4( 164.0f / 255.0f, 84.0f / 255.0f, 84.0f / 255.0f, 1.f ) };
|
||||||
|
auto const waitcolor { glm::vec4( 164.0f / 255.0f, 132.0f / 255.0f, 84.0f / 255.0f, 1.f ) };
|
||||||
auto const readycolor { glm::vec4( 84.0f / 255.0f, 164.0f / 255.0f, 132.0f / 255.0f, 1.f ) };
|
auto const readycolor { glm::vec4( 84.0f / 255.0f, 164.0f / 255.0f, 132.0f / 255.0f, 1.f ) };
|
||||||
|
|
||||||
// header
|
// header
|
||||||
text_lines.emplace_back( "+-----+------------------------------------+-------+-----+", Global.UITextColor );
|
m_tablelines.emplace_back( u8"┌─────┬────────────────────────────────────┬─────────┬─────┐", Global.UITextColor );
|
||||||
|
|
||||||
TMTableLine const *tableline;
|
TMTableLine const *tableline;
|
||||||
for( int i = owner->iStationStart; i <= table->StationCount; ++i ) {
|
for( int i = owner->iStationStart; i <= table->StationCount; ++i ) {
|
||||||
// wyświetlenie pozycji z rozkładu
|
// wyświetlenie pozycji z rozkładu
|
||||||
tableline = table->TimeTable + i; // linijka rozkładu
|
tableline = table->TimeTable + i; // linijka rozkładu
|
||||||
|
|
||||||
std::string vmax =
|
bool vmaxchange { true };
|
||||||
" "
|
if( i > owner->iStationStart ) {
|
||||||
+ to_string( tableline->vmax, 0 );
|
auto const *previoustableline { tableline - 1 };
|
||||||
vmax = vmax.substr( vmax.size() - 3, 3 ); // z wyrównaniem do prawej
|
if( tableline->vmax == previoustableline->vmax ) {
|
||||||
std::string const station = (
|
vmaxchange = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string vmax { " " };
|
||||||
|
if( true == vmaxchange ) {
|
||||||
|
vmax += to_string( tableline->vmax, 0 );
|
||||||
|
vmax = vmax.substr( vmax.size() - 3, 3 ); // z wyrównaniem do prawej
|
||||||
|
}
|
||||||
|
auto const station { (
|
||||||
Bezogonkow( tableline->StationName, true )
|
Bezogonkow( tableline->StationName, true )
|
||||||
+ " " )
|
+ " " )
|
||||||
.substr( 0, 34 );
|
.substr( 0, 34 ) };
|
||||||
std::string const location = (
|
auto const location { (
|
||||||
( tableline->km > 0.0 ?
|
( tableline->km > 0.0 ?
|
||||||
to_string( tableline->km, 2 ) :
|
to_string( tableline->km, 2 ) :
|
||||||
"" )
|
"" )
|
||||||
+ " " )
|
+ " " )
|
||||||
.substr( 0, 34 - tableline->StationWare.size() );
|
.substr( 0, 34 - tableline->StationWare.size() ) };
|
||||||
std::string const arrival = (
|
auto const arrival { (
|
||||||
tableline->Ah >= 0 ?
|
tableline->Ah >= 0 ?
|
||||||
to_string( int( 100 + tableline->Ah ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Am ) ).substr( 1, 2 ) :
|
to_string( int( 100 + tableline->Ah ) ).substr( 1, 2 ) + ":" + to_minutes_str( tableline->Am, true, 3 ) :
|
||||||
" | " );
|
u8" │ " ) };
|
||||||
std::string const departure = (
|
auto const departure { (
|
||||||
tableline->Dh >= 0 ?
|
tableline->Dh >= 0 ?
|
||||||
to_string( int( 100 + tableline->Dh ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Dm ) ).substr( 1, 2 ) :
|
to_string( int( 100 + tableline->Dh ) ).substr( 1, 2 ) + ":" + to_minutes_str( tableline->Dm, true, 3 ) :
|
||||||
" | " );
|
u8" │ " ) };
|
||||||
auto const candeparture = (
|
auto const candeparture { (
|
||||||
( owner->iStationStart < table->StationIndex )
|
( owner->iStationStart < table->StationIndex )
|
||||||
&& ( i < table->StationIndex )
|
&& ( i < table->StationIndex )
|
||||||
&& ( ( tableline->Ah < 0 ) // pass-through, always valid
|
&& ( ( tableline->Ah < 0 ) // pass-through, always valid
|
||||||
|| ( time.wHour * 60 + time.wMinute >= tableline->Dh * 60 + tableline->Dm ) ) );
|
|| ( time.wHour * 60 + time.wMinute + time.wSecond * 0.0167 >= tableline->Dh * 60 + tableline->Dm ) ) ) };
|
||||||
auto traveltime =
|
auto const loadchangeinprogress { ( ( static_cast<int>( std::ceil( -1.0 * owner->fStopTime ) ) ) > 0 ) };
|
||||||
" "
|
auto const isatpassengerstop { ( true == owner->IsAtPassengerStop ) && ( vehicle->MoverParameters->Vel < 1.0 ) };
|
||||||
+ ( i < 2 ? "" :
|
auto const traveltime { (
|
||||||
tableline->Ah >= 0 ? to_string( CompareTime( table->TimeTable[ i - 1 ].Dh, table->TimeTable[ i - 1 ].Dm, tableline->Ah, tableline->Am ), 0 ) :
|
i < 2 ? " " :
|
||||||
to_string( std::max( 0.0, CompareTime( table->TimeTable[ i - 1 ].Dh, table->TimeTable[ i - 1 ].Dm, tableline->Dh, tableline->Dm ) - 0.5 ), 0 ) );
|
tableline->Ah >= 0 ? to_minutes_str( CompareTime( table->TimeTable[ i - 1 ].Dh, table->TimeTable[ i - 1 ].Dm, tableline->Ah, tableline->Am ), false, 3 ) :
|
||||||
traveltime = traveltime.substr( traveltime.size() - 3, 3 ); // z wyrównaniem do prawej
|
to_minutes_str( std::max( 0.0, CompareTime( table->TimeTable[ i - 1 ].Dh, table->TimeTable[ i - 1 ].Dm, tableline->Dh, tableline->Dm ) - 0.5 ), false, 3 ) ) };
|
||||||
|
auto const linecolor { (
|
||||||
text_lines.emplace_back(
|
( i != owner->iStationStart ) ? Global.UITextColor :
|
||||||
( "| " + vmax + " | " + station + " | " + arrival + " | " + traveltime + " |" ),
|
loadchangeinprogress ? loadingcolor :
|
||||||
( candeparture ?
|
candeparture ? readycolor : // czas minął i odjazd był, to nazwa stacji będzie na zielono
|
||||||
readycolor :// czas minął i odjazd był, to nazwa stacji będzie na zielono
|
isatpassengerstop ? waitcolor :
|
||||||
Global.UITextColor ) );
|
Global.UITextColor ) };
|
||||||
text_lines.emplace_back(
|
m_tablelines.emplace_back(
|
||||||
( "| | " + location + tableline->StationWare + " | " + departure + " | |" ),
|
( u8"│ " + vmax + u8" │ " + station + u8" │ " + arrival + u8" │ " + traveltime + u8" │" ),
|
||||||
( candeparture ?
|
linecolor );
|
||||||
readycolor :// czas minął i odjazd był, to nazwa stacji będzie na zielono
|
m_tablelines.emplace_back(
|
||||||
Global.UITextColor ) );
|
( u8"│ │ " + location + tableline->StationWare + u8" │ " + departure + u8" │ │" ),
|
||||||
|
linecolor );
|
||||||
// divider/footer
|
// divider/footer
|
||||||
text_lines.emplace_back( "+-----+------------------------------------+-------+-----+", Global.UITextColor );
|
if( i < table->StationCount ) {
|
||||||
|
auto const *nexttableline { tableline + 1 };
|
||||||
|
if( tableline->vmax == nexttableline->vmax ) {
|
||||||
|
m_tablelines.emplace_back( u8"│ ├────────────────────────────────────┼─────────┼─────┤", Global.UITextColor );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_tablelines.emplace_back( u8"├─────┼────────────────────────────────────┼─────────┼─────┤", Global.UITextColor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_tablelines.emplace_back( u8"└─────┴────────────────────────────────────┴─────────┴─────┘", Global.UITextColor );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // is_expanded
|
} // is_expanded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
timetable_panel::render() {
|
||||||
|
|
||||||
|
if( false == is_open ) { return; }
|
||||||
|
if( true == text_lines.empty() ) { return; }
|
||||||
|
|
||||||
|
auto flags =
|
||||||
|
ImGuiWindowFlags_NoFocusOnAppearing
|
||||||
|
| ImGuiWindowFlags_NoCollapse
|
||||||
|
| ( size.x > 0 ? ImGuiWindowFlags_NoResize : 0 );
|
||||||
|
|
||||||
|
if( size.x > 0 ) {
|
||||||
|
ImGui::SetNextWindowSize( ImVec2( size.x, size.y ) );
|
||||||
|
}
|
||||||
|
if( size_min.x > 0 ) {
|
||||||
|
ImGui::SetNextWindowSizeConstraints( ImVec2( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) );
|
||||||
|
}
|
||||||
|
auto const panelname { (
|
||||||
|
title.empty() ?
|
||||||
|
name :
|
||||||
|
title )
|
||||||
|
+ "###" + name };
|
||||||
|
if( true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) {
|
||||||
|
for( auto const &line : text_lines ) {
|
||||||
|
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||||
|
}
|
||||||
|
if( is_expanded ) {
|
||||||
|
ImGui::PushStyleVar( ImGuiStyleVar_ItemSpacing, ImVec2( 1, 0 ) );
|
||||||
|
for( auto const &line : m_tablelines ) {
|
||||||
|
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||||
|
}
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
debug_panel::update() {
|
debug_panel::update() {
|
||||||
|
|
||||||
@@ -725,7 +785,8 @@ debug_panel::update_section_engine( std::vector<text_line> &Output ) {
|
|||||||
|
|
||||||
std::string parameterstext = "param value";
|
std::string parameterstext = "param value";
|
||||||
std::vector< std::pair <std::string, double> > const paramvalues {
|
std::vector< std::pair <std::string, double> > const paramvalues {
|
||||||
{ "efill: ", mover.dizel_fill },
|
{ " rpm: ", mover.enrot * 60.0 },
|
||||||
|
{ "efill: ", mover.dizel_fill },
|
||||||
{ "etorq: ", mover.dizel_Torque },
|
{ "etorq: ", mover.dizel_Torque },
|
||||||
{ "creal: ", mover.dizel_engage },
|
{ "creal: ", mover.dizel_engage },
|
||||||
{ "cdesi: ", mover.dizel_engagestate },
|
{ "cdesi: ", mover.dizel_engagestate },
|
||||||
|
|||||||
@@ -50,12 +50,14 @@ public:
|
|||||||
: ui_panel( Name, Isopen ) {}
|
: ui_panel( Name, Isopen ) {}
|
||||||
|
|
||||||
void update() override;
|
void update() override;
|
||||||
|
void render() override;
|
||||||
|
|
||||||
bool is_expanded{ false };
|
bool is_expanded{ false };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// members
|
// members
|
||||||
std::array<char, 256> m_buffer;
|
std::array<char, 256> m_buffer;
|
||||||
|
std::vector<text_line> m_tablelines;
|
||||||
};
|
};
|
||||||
|
|
||||||
class debug_panel : public ui_panel {
|
class debug_panel : public ui_panel {
|
||||||
|
|||||||
26
mtable.cpp
26
mtable.cpp
@@ -51,7 +51,7 @@ bool TTrainParameters::IsStop() const
|
|||||||
|
|
||||||
bool TTrainParameters::UpdateMTable( scenario_time const &Time, std::string const &NewName ) {
|
bool TTrainParameters::UpdateMTable( scenario_time const &Time, std::string const &NewName ) {
|
||||||
|
|
||||||
return UpdateMTable( Time.data().wHour, Time.data().wMinute, NewName );
|
return UpdateMTable( Time.data().wHour, Time.data().wMinute + Time.data().wSecond * 0.0167, NewName );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TTrainParameters::UpdateMTable(double hh, double mm, std::string const &NewName)
|
bool TTrainParameters::UpdateMTable(double hh, double mm, std::string const &NewName)
|
||||||
@@ -358,12 +358,12 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
|||||||
if (s.find(hrsd) != std::string::npos)
|
if (s.find(hrsd) != std::string::npos)
|
||||||
{
|
{
|
||||||
record->Ah = atoi( s.substr(0, s.find(hrsd)).c_str()); // godzina przyjazdu
|
record->Ah = atoi( s.substr(0, s.find(hrsd)).c_str()); // godzina przyjazdu
|
||||||
record->Am = atoi(s.substr(s.find(hrsd) + 1, s.length()).c_str()); // minuta przyjazdu
|
record->Am = atof(s.substr(s.find(hrsd) + 1, s.length()).c_str()); // minuta przyjazdu
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
record->Ah = TimeTable[StationCount - 1].Ah; // godzina z poprzedniej pozycji
|
record->Ah = TimeTable[StationCount - 1].Ah; // godzina z poprzedniej pozycji
|
||||||
record->Am = atoi(s.c_str()); // bo tylko minuty podane
|
record->Am = atof(s.c_str()); // bo tylko minuty podane
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
do
|
do
|
||||||
@@ -408,12 +408,12 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
|||||||
if (s.find(hrsd) != std::string::npos)
|
if (s.find(hrsd) != std::string::npos)
|
||||||
{
|
{
|
||||||
record->Dh = atoi(s.substr(0, s.find(hrsd)).c_str()); // godzina odjazdu
|
record->Dh = atoi(s.substr(0, s.find(hrsd)).c_str()); // godzina odjazdu
|
||||||
record->Dm = atoi(s.substr(s.find(hrsd) + 1, s.length()).c_str()); // minuta odjazdu
|
record->Dm = atof(s.substr(s.find(hrsd) + 1, s.length()).c_str()); // minuta odjazdu
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
record->Dh = TimeTable[StationCount - 1].Dh; // godzina z poprzedniej pozycji
|
record->Dh = TimeTable[StationCount - 1].Dh; // godzina z poprzedniej pozycji
|
||||||
record->Dm = atoi(s.c_str()); // bo tylko minuty podane
|
record->Dm = atof(s.c_str()); // bo tylko minuty podane
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -475,20 +475,20 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
|||||||
if( timeoffset != 0 ) // jeżeli jest przesunięcie rozkładu
|
if( timeoffset != 0 ) // jeżeli jest przesunięcie rozkładu
|
||||||
{
|
{
|
||||||
long i_end = StationCount + 1;
|
long i_end = StationCount + 1;
|
||||||
int adjustedtime; // do zwiększania czasu
|
float adjustedtime; // do zwiększania czasu
|
||||||
for (auto i = 1; i < i_end; ++i) // bez with, bo ciężko się przenosi na C++
|
for (auto i = 1; i < i_end; ++i) // bez with, bo ciężko się przenosi na C++
|
||||||
{
|
{
|
||||||
if ((TimeTable[i].Ah >= 0))
|
if ((TimeTable[i].Ah >= 0))
|
||||||
{
|
{
|
||||||
adjustedtime = clamp_circular( TimeTable[i].Ah * 60 + TimeTable[i].Am + timeoffset, 24 * 60 ); // nowe minuty
|
adjustedtime = clamp_circular<float>( TimeTable[i].Ah * 60 + TimeTable[i].Am + timeoffset, 24 * 60 ); // nowe minuty
|
||||||
TimeTable[i].Am = adjustedtime % 60;
|
TimeTable[i].Am = (int(60 * adjustedtime) % 3600) / 60.f;
|
||||||
TimeTable[i].Ah = (adjustedtime / 60) % 24;
|
TimeTable[i].Ah = int((adjustedtime) / 60) % 24;
|
||||||
}
|
}
|
||||||
if ((TimeTable[i].Dh >= 0))
|
if ((TimeTable[i].Dh >= 0))
|
||||||
{
|
{
|
||||||
adjustedtime = clamp_circular( TimeTable[i].Dh * 60 + TimeTable[i].Dm + timeoffset, 24 * 60 ); // nowe minuty
|
adjustedtime = clamp_circular<float>( TimeTable[i].Dh * 60 + TimeTable[i].Dm + timeoffset, 24 * 60 ); // nowe minuty
|
||||||
TimeTable[i].Dm = adjustedtime % 60;
|
TimeTable[i].Dm = (int(60 * adjustedtime) % 3600) / 60.f;
|
||||||
TimeTable[i].Dh = (adjustedtime / 60) % 24;
|
TimeTable[i].Dh = int((adjustedtime) / 60) % 24;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -532,6 +532,8 @@ void TTrainParameters::serialize( dictionary_source *Output ) const {
|
|||||||
Output->insert( "train_enginetype", LocSeries );
|
Output->insert( "train_enginetype", LocSeries );
|
||||||
Output->insert( "train_engineload", LocLoad );
|
Output->insert( "train_engineload", LocLoad );
|
||||||
|
|
||||||
|
Output->insert( "train_stationfrom", Relation1 );
|
||||||
|
Output->insert( "train_stationto", Relation2 );
|
||||||
Output->insert( "train_stationindex", StationIndex );
|
Output->insert( "train_stationindex", StationIndex );
|
||||||
Output->insert( "train_stationcount", StationCount );
|
Output->insert( "train_stationcount", StationCount );
|
||||||
if( StationCount > 0 ) {
|
if( StationCount > 0 ) {
|
||||||
|
|||||||
10
mtable.h
10
mtable.h
@@ -24,18 +24,18 @@ static char const *hrsd = ".";
|
|||||||
|
|
||||||
struct TMTableLine
|
struct TMTableLine
|
||||||
{
|
{
|
||||||
double km; // kilometraz linii
|
float km; // kilometraz linii
|
||||||
double vmax; // predkosc rozkladowa przed przystankiem
|
float vmax; // predkosc rozkladowa przed przystankiem
|
||||||
// StationName:string[32]; //nazwa stacji ('_' zamiast spacji)
|
// StationName:string[32]; //nazwa stacji ('_' zamiast spacji)
|
||||||
// StationWare:string[32]; //typ i wyposazenie stacji, oddz. przecinkami}
|
// StationWare:string[32]; //typ i wyposazenie stacji, oddz. przecinkami}
|
||||||
std::string StationName; // nazwa stacji ('_' zamiast spacji)
|
std::string StationName; // nazwa stacji ('_' zamiast spacji)
|
||||||
std::string StationWare; // typ i wyposazenie stacji, oddz. przecinkami}
|
std::string StationWare; // typ i wyposazenie stacji, oddz. przecinkami}
|
||||||
int TrackNo; // ilosc torow szlakowych
|
int TrackNo; // ilosc torow szlakowych
|
||||||
int Ah;
|
int Ah;
|
||||||
int Am; // godz. i min. przyjazdu, -1 gdy bez postoju
|
float Am; // godz. i min. przyjazdu, -1 gdy bez postoju
|
||||||
int Dh;
|
int Dh;
|
||||||
int Dm; // godz. i min. odjazdu
|
float Dm; // godz. i min. odjazdu
|
||||||
double tm; // czas jazdy do tej stacji w min. (z kolumny)
|
float tm; // czas jazdy do tej stacji w min. (z kolumny)
|
||||||
TMTableLine()
|
TMTableLine()
|
||||||
{
|
{
|
||||||
km = 0;
|
km = 0;
|
||||||
|
|||||||
59
renderer.cpp
59
renderer.cpp
@@ -32,17 +32,18 @@ int const EU07_ENVIRONMENTBUFFERSIZE { 256 }; // size of (square) environmental
|
|||||||
void
|
void
|
||||||
opengl_light::apply_intensity( float const Factor ) {
|
opengl_light::apply_intensity( float const Factor ) {
|
||||||
|
|
||||||
if( Factor == 1.0 ) {
|
if( Factor == 1.f ) {
|
||||||
|
|
||||||
::glLightfv( id, GL_AMBIENT, glm::value_ptr( ambient ) );
|
::glLightfv( id, GL_AMBIENT, glm::value_ptr( ambient ) );
|
||||||
::glLightfv( id, GL_DIFFUSE, glm::value_ptr( diffuse ) );
|
::glLightfv( id, GL_DIFFUSE, glm::value_ptr( diffuse ) );
|
||||||
::glLightfv( id, GL_SPECULAR, glm::value_ptr( specular ) );
|
::glLightfv( id, GL_SPECULAR, glm::value_ptr( specular ) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
auto const factor{ clamp( Factor, 0.05f, 1.f ) };
|
||||||
// temporary light scaling mechanics (ultimately this work will be left to the shaders
|
// temporary light scaling mechanics (ultimately this work will be left to the shaders
|
||||||
glm::vec4 scaledambient( ambient.r * Factor, ambient.g * Factor, ambient.b * Factor, ambient.a );
|
glm::vec4 scaledambient( ambient.r * factor, ambient.g * factor, ambient.b * factor, ambient.a );
|
||||||
glm::vec4 scaleddiffuse( diffuse.r * Factor, diffuse.g * Factor, diffuse.b * Factor, diffuse.a );
|
glm::vec4 scaleddiffuse( diffuse.r * factor, diffuse.g * factor, diffuse.b * factor, diffuse.a );
|
||||||
glm::vec4 scaledspecular( specular.r * Factor, specular.g * Factor, specular.b * Factor, specular.a );
|
glm::vec4 scaledspecular( specular.r * factor, specular.g * factor, specular.b * factor, specular.a );
|
||||||
glLightfv( id, GL_AMBIENT, glm::value_ptr( scaledambient ) );
|
glLightfv( id, GL_AMBIENT, glm::value_ptr( scaledambient ) );
|
||||||
glLightfv( id, GL_DIFFUSE, glm::value_ptr( scaleddiffuse ) );
|
glLightfv( id, GL_DIFFUSE, glm::value_ptr( scaleddiffuse ) );
|
||||||
glLightfv( id, GL_SPECULAR, glm::value_ptr( scaledspecular ) );
|
glLightfv( id, GL_SPECULAR, glm::value_ptr( scaledspecular ) );
|
||||||
@@ -2194,34 +2195,36 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
|||||||
m_renderspecular = true; // vehicles are rendered with specular component. static models without, at least for the time being
|
m_renderspecular = true; // vehicles are rendered with specular component. static models without, at least for the time being
|
||||||
// render
|
// render
|
||||||
if( Dynamic->mdLowPolyInt ) {
|
if( Dynamic->mdLowPolyInt ) {
|
||||||
// low poly interior
|
// HACK: reduce light level for vehicle interior if there's strong global lighting source
|
||||||
/*
|
auto const luminance { static_cast<float>( 0.5 * ( std::max( 0.3, Global.fLuminance - Global.Overcast ) ) ) };
|
||||||
if( ( true == FreeFlyModeFlag )
|
m_sunlight.apply_intensity(
|
||||||
|| ( ( Dynamic->mdKabina == nullptr ) || ( false == Dynamic->bDisplayCab ) ) ) {
|
clamp( (
|
||||||
*/
|
Dynamic->fShade > 0.f ?
|
||||||
/*
|
Dynamic->fShade :
|
||||||
// enable cab light if needed
|
1.f )
|
||||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
- luminance,
|
||||||
|
0.f, 1.f ) );
|
||||||
|
|
||||||
// crude way to light the cabin, until we have something more complete in place
|
// low poly interior
|
||||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( Dynamic->InteriorLight * Dynamic->InteriorLightLevel ) );
|
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
|
||||||
}
|
// HACK: if the model has low poly interior, we presume the load is placed inside and also affected by reduced light level
|
||||||
*/
|
if( Dynamic->mdLoad ) {
|
||||||
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
|
// renderowanie nieprzezroczystego ładunku
|
||||||
/*
|
Render( Dynamic->mdLoad, Dynamic->Material(), squaredistance, { 0.f, Dynamic->LoadOffset, 0.f }, {} );
|
||||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
|
||||||
// reset the overall ambient
|
|
||||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( m_baseambient ) );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
m_sunlight.apply_intensity( Dynamic->fShade > 0.f ? Dynamic->fShade : 1.f );
|
||||||
}
|
}
|
||||||
if( Dynamic->mdModel )
|
else {
|
||||||
|
// HACK: if the model lacks low poly interior, we presume the load is placed outside
|
||||||
|
if( Dynamic->mdLoad ) {
|
||||||
|
// renderowanie nieprzezroczystego ładunku
|
||||||
|
Render( Dynamic->mdLoad, Dynamic->Material(), squaredistance, { 0.f, Dynamic->LoadOffset, 0.f }, {} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( Dynamic->mdModel ) {
|
||||||
Render( Dynamic->mdModel, Dynamic->Material(), squaredistance );
|
Render( Dynamic->mdModel, Dynamic->Material(), squaredistance );
|
||||||
if( Dynamic->mdLoad ) // renderowanie nieprzezroczystego ładunku
|
}
|
||||||
Render( Dynamic->mdLoad, Dynamic->Material(), squaredistance, { 0.f, Dynamic->LoadOffset, 0.f }, {} );
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
m_renderspecular = false;
|
m_renderspecular = false;
|
||||||
if( Dynamic->fShade > 0.0f ) {
|
if( Dynamic->fShade > 0.0f ) {
|
||||||
|
|||||||
@@ -163,14 +163,22 @@ state_serializer::deserialize_atmo( cParser &Input, scene::scratch_data &Scratch
|
|||||||
// atmosphere color; legacy parameter, no longer used
|
// atmosphere color; legacy parameter, no longer used
|
||||||
Input.getTokens( 3 );
|
Input.getTokens( 3 );
|
||||||
// fog range
|
// fog range
|
||||||
Input.getTokens( 2 );
|
{
|
||||||
Input
|
double fograngestart, fograngeend;
|
||||||
>> Global.fFogStart
|
Input.getTokens( 2 );
|
||||||
>> Global.fFogEnd;
|
Input
|
||||||
|
>> fograngestart
|
||||||
|
>> fograngeend;
|
||||||
|
|
||||||
if( Global.fFogEnd > 0.0 ) {
|
if( Global.fFogEnd != 0.0 ) {
|
||||||
// fog colour; optional legacy parameter, no longer used
|
// fog colour; optional legacy parameter, no longer used
|
||||||
Input.getTokens( 3 );
|
Input.getTokens( 3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
Global.fFogEnd =
|
||||||
|
clamp(
|
||||||
|
Random( std::min( fograngestart, fograngeend ), std::max( fograngestart, fograngeend ) ),
|
||||||
|
10.0, 2000.0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string token { Input.getToken<std::string>() };
|
std::string token { Input.getToken<std::string>() };
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ init() {
|
|||||||
"all doors (open)",
|
"all doors (open)",
|
||||||
"all doors (close)",
|
"all doors (close)",
|
||||||
"doorstep",
|
"doorstep",
|
||||||
|
"door control mode",
|
||||||
"departure signal",
|
"departure signal",
|
||||||
"upper headlight",
|
"upper headlight",
|
||||||
"left headlight",
|
"left headlight",
|
||||||
@@ -296,6 +297,7 @@ init() {
|
|||||||
"drzwi (otworz)",
|
"drzwi (otworz)",
|
||||||
"drzwi (zamknij)",
|
"drzwi (zamknij)",
|
||||||
"stopien drzwi",
|
"stopien drzwi",
|
||||||
|
"tryb sterowania drzwiami",
|
||||||
"sygnal odjazdu",
|
"sygnal odjazdu",
|
||||||
"reflektor gorny",
|
"reflektor gorny",
|
||||||
"reflektor lewy",
|
"reflektor lewy",
|
||||||
@@ -414,6 +416,7 @@ init() {
|
|||||||
"doorallon_sw:",
|
"doorallon_sw:",
|
||||||
"dooralloff_sw:",
|
"dooralloff_sw:",
|
||||||
"doorstep_sw:",
|
"doorstep_sw:",
|
||||||
|
"doormode_sw:",
|
||||||
"departure_signal_bt:",
|
"departure_signal_bt:",
|
||||||
"upperlight_sw:",
|
"upperlight_sw:",
|
||||||
"leftlight_sw:",
|
"leftlight_sw:",
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ enum string {
|
|||||||
cab_doorallon_sw,
|
cab_doorallon_sw,
|
||||||
cab_dooralloff_sw,
|
cab_dooralloff_sw,
|
||||||
cab_doorstep_sw,
|
cab_doorstep_sw,
|
||||||
|
cab_doormode_sw,
|
||||||
cab_departure_signal_bt,
|
cab_departure_signal_bt,
|
||||||
cab_upperlight_sw,
|
cab_upperlight_sw,
|
||||||
cab_leftlight_sw,
|
cab_leftlight_sw,
|
||||||
|
|||||||
@@ -101,8 +101,15 @@ ui_layer::init( GLFWwindow *Window ) {
|
|||||||
|
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
|
|
||||||
|
static ImWchar const glyphranges[] = {
|
||||||
|
0x0020, 0x00FF, // ascii + extension
|
||||||
|
0x2070, 0x2079, // superscript
|
||||||
|
0x2500, 0x256C, // box drawings
|
||||||
|
0,
|
||||||
|
};
|
||||||
m_imguiio = &ImGui::GetIO();
|
m_imguiio = &ImGui::GetIO();
|
||||||
m_imguiio->Fonts->AddFontFromFileTTF("fonts/dejavusansmono.ttf", 13.0f);
|
m_imguiio->Fonts->AddFontFromFileTTF( "fonts/dejavusansmono.ttf", 13.0f, nullptr, &glyphranges[ 0 ] );
|
||||||
|
|
||||||
ImGui::StyleColorsClassic();
|
ImGui::StyleColorsClassic();
|
||||||
ImGui_ImplGlfw_InitForOpenGL(m_window);
|
ImGui_ImplGlfw_InitForOpenGL(m_window);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
This Source Code Form is subject to the
|
This Source Code Form is subject to the
|
||||||
terms of the Mozilla Public License, v.
|
terms of the Mozilla Public License, v.
|
||||||
2.0. If a copy of the MPL was not
|
2.0. If a copy of the MPL was not
|
||||||
@@ -246,6 +246,24 @@ std::string to_hex_str( int const Value, int const Width )
|
|||||||
return converter.str();
|
return converter.str();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string const fractionlabels[] = { " ", u8"¹", u8"²", u8"³", u8"⁴", u8"⁵", u8"⁶", u8"⁷", u8"⁸", u8"⁹" };
|
||||||
|
|
||||||
|
std::string to_minutes_str( float const Minutes, bool const Leadingzero, int const Width ) {
|
||||||
|
|
||||||
|
float minutesintegral;
|
||||||
|
auto const minutesfractional { std::modf( Minutes, &minutesintegral ) };
|
||||||
|
auto const width { Width - 1 };
|
||||||
|
auto minutes = (
|
||||||
|
std::string( width - 1, ' ' )
|
||||||
|
+ ( Leadingzero ?
|
||||||
|
to_string( 100 + minutesintegral ).substr( 1, 2 ) :
|
||||||
|
to_string( minutesintegral, 0 ) ) );
|
||||||
|
return (
|
||||||
|
minutes.substr( minutes.size() - width, width )
|
||||||
|
+ fractionlabels[ static_cast<int>( std::floor( minutesfractional * 10 + 0.1 ) ) ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int stol_def(const std::string &str, const int &DefaultValue) {
|
int stol_def(const std::string &str, const int &DefaultValue) {
|
||||||
|
|
||||||
int result { DefaultValue };
|
int result { DefaultValue };
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ std::string to_string(double Value);
|
|||||||
std::string to_string(double Value, int precision);
|
std::string to_string(double Value, int precision);
|
||||||
std::string to_string(double Value, int precision, int width);
|
std::string to_string(double Value, int precision, int width);
|
||||||
std::string to_hex_str( int const Value, int const width = 4 );
|
std::string to_hex_str( int const Value, int const width = 4 );
|
||||||
|
std::string to_minutes_str( float const Minutes, bool const Leadingzero, int const Width );
|
||||||
|
|
||||||
inline std::string to_string(bool Value) {
|
inline std::string to_string(bool Value) {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user