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

e43ea7fc conflict mess up fix

This commit is contained in:
tmj-fstate
2019-10-12 19:53:42 +02:00
parent e43ea7fcfe
commit 0e20ec7f08
5 changed files with 680 additions and 404 deletions

View File

@@ -1001,68 +1001,145 @@ double TMoverParameters::PipeRatio(void)
// Q: 20160716 // Q: 20160716
// Wykrywanie kolizji // Wykrywanie kolizji
// ************************************************************************************************* // *************************************************************************************************
void TMoverParameters::CollisionDetect(int CouplerN, double dt) void TMoverParameters::CollisionDetect(int const End, double const dt)
{ {
double CCF, Vprev, VprevC; if( Neighbours[ End ].vehicle == nullptr ) { return; } // shouldn't normally happen but, eh
bool VirtualCoupling;
CCF = 0; auto &coupler { Couplers[ End ] };
// with Couplers[CouplerN] do auto *othervehicle { Neighbours[ End ].vehicle->MoverParameters };
auto &coupler = Couplers[ CouplerN ]; auto const otherend { Neighbours[ End ].vehicle_end };
auto &othercoupler { othervehicle->Couplers[ otherend ] };
if (coupler.Connected != nullptr) auto velocity { V };
{ auto othervehiclevelocity { othervehicle->V };
VirtualCoupling = (coupler.CouplingFlag == ctrain_virtual); // calculate collision force and new velocities for involved vehicles
Vprev = V; auto const VirtualCoupling { ( coupler.CouplingFlag == coupling::faux ) };
VprevC = coupler.Connected->V; auto CCF { 0.0 };
switch (CouplerN)
{ switch( End ) {
case 0: case 0: {
CCF = CCF =
ComputeCollision( ComputeCollision(
V, velocity, othervehiclevelocity,
coupler.Connected->V, TotalMass, othervehicle->TotalMass,
TotalMass, ( coupler.beta + othercoupler.beta ) / 2.0,
coupler.Connected->TotalMass, VirtualCoupling )
(coupler.beta + coupler.Connected->Couplers[coupler.ConnectedNr].beta) / 2.0, / ( dt );
VirtualCoupling)
/ (dt);
break; // yB: ej ej ej, a po break; // yB: ej ej ej, a po
case 1: }
case 1: {
CCF = CCF =
ComputeCollision( ComputeCollision(
coupler.Connected->V, othervehiclevelocity, velocity,
V, othervehicle->TotalMass, TotalMass,
coupler.Connected->TotalMass, ( coupler.beta + othercoupler.beta ) / 2.0,
TotalMass, VirtualCoupling )
(coupler.beta + coupler.Connected->Couplers[coupler.ConnectedNr].beta) / 2.0, / ( dt );
VirtualCoupling) break;
/ (dt);
break; // czemu tu jest +0.01??
} }
AccS = AccS + (V - Vprev) / dt; // korekta przyspieszenia o siły wynikające ze zderzeń? default: {
coupler.Connected->AccS += (coupler.Connected->V - VprevC) / dt; break;
if ((coupler.Dist > 0) && (!VirtualCoupling)) }
if (FuzzyLogic(abs(CCF), 5.0 * (coupler.FmaxC + 1.0), p_coupldmg)) }
{ //! zerwanie sprzegu
if (SetFlag(DamageFlag, dtrain_coupling))
EventFlag = true;
if ((coupler.CouplingFlag & ctrain_pneumatic) == ctrain_pneumatic) if( ( coupler.Dist < 0 )
AlarmChainFlag = true; // hamowanie nagle - zerwanie przewodow hamulcowych && ( FuzzyLogic( std::abs( CCF ), 5.0 * ( coupler.FmaxC + 1.0 ), p_coupldmg ) ) ) {
coupler.CouplingFlag = 0; // small chance to smash the coupler if it's hit with excessive force
damage_coupler( End );
}
switch (CouplerN) // wyzerowanie flag podlaczenia ale ciagle sa wirtualnie polaczone auto const safevelocitylimit { 15.0 };
{ auto const velocitydifference {
case 0: glm::length(
coupler.Connected->Couplers[1].CouplingFlag = 0; glm::angleAxis( Rot.Rz, glm::dvec3{ 0, 1, 0 } ) * V
break; - glm::angleAxis( othervehicle->Rot.Rz, glm::dvec3{ 0, 1, 0 } ) * othervehicle->V )
case 1: * 3.6 }; // m/s -> km/h
coupler.Connected->Couplers[0].CouplingFlag = 0;
break; if( velocitydifference > safevelocitylimit ) {
} // HACK: crude estimation for potential derail, will take place with velocity difference > 15 km/h adjusted for vehicle mass ratio
WriteLog( "Bad driving: " + Name + " broke a coupler" ); if( ( false == TestFlag( DamageFlag, dtrain_out ) )
|| ( false == TestFlag( othervehicle->DamageFlag, dtrain_out ) ) ) {
WriteLog( "Bad driving: " + Name + " and " + othervehicle->Name + " collided with velocity " + to_string( velocitydifference, 0 ) + " km/h" );
}
if( velocitydifference > safevelocitylimit * ( TotalMass / othervehicle->TotalMass ) ) {
derail( 5 );
}
if( velocitydifference > safevelocitylimit * ( othervehicle->TotalMass / TotalMass ) ) {
othervehicle->derail( 5 );
}
}
// adjust velocity and acceleration of affected vehicles
if( false == TestFlag( DamageFlag, dtrain_out ) ) {
auto const accelerationchange{ ( velocity - V ) / dt };
// if( accelerationchange / AccS < 1.0 ) {
// HACK: prevent excessive vehicle pinball cases
AccS += accelerationchange;
// AccS = clamp( AccS, -2.0, 2.0 );
V = velocity;
// }
}
if( false == TestFlag( othervehicle->DamageFlag, dtrain_out ) ) {
auto const othervehicleaccelerationchange{ ( othervehiclevelocity - othervehicle->V ) / dt };
// if( othervehicleaccelerationchange / othervehicle->AccS < 1.0 ) {
// HACK: prevent excessive vehicle pinball cases
othervehicle->AccS += othervehicleaccelerationchange;
othervehicle->V = othervehiclevelocity;
// }
}
}
void
TMoverParameters::damage_coupler( int const End ) {
auto &coupler{ Couplers[ End ] };
if( coupler.CouplerType == TCouplerType::Articulated ) { return; } // HACK: don't break articulated couplings no matter what
if( SetFlag( DamageFlag, dtrain_coupling ) )
EventFlag = true;
if( ( coupler.CouplingFlag & coupling::brakehose ) == coupling::brakehose ) {
// hamowanie nagle - zerwanie przewodow hamulcowych
AlarmChainFlag = true;
}
coupler.CouplingFlag = 0;
if( coupler.Connected != nullptr ) {
switch( End ) {
// break connection with other vehicle, if there's any
case 0: {
coupler.Connected->Couplers[ end::rear ].CouplingFlag = coupling::faux;
break;
} }
case 1: {
coupler.Connected->Couplers[ end::front ].CouplingFlag = coupling::faux;
break;
}
default: {
break;
}
}
}
WriteLog( "Bad driving: " + Name + " broke a coupler" );
}
void
TMoverParameters::derail( int const Reason ) {
if( SetFlag( DamageFlag, dtrain_out ) ) {
DerailReason = Reason; // TODO: enum derail causes
EventFlag = true;
MainSwitch( false, range_t::local );
AccS *= 0.65;
V *= 0.65;
WriteLog( "Bad driving: " + Name + " derailed" );
} }
} }
@@ -1071,7 +1148,7 @@ void TMoverParameters::CollisionDetect(int CouplerN, double dt)
// ************************************************************************************************* // *************************************************************************************************
double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShape &Shape, double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShape &Shape,
TTrackParam &Track, TTractionParam &ElectricTraction, TTrackParam &Track, TTractionParam &ElectricTraction,
const TLocation &NewLoc, TRotation &NewRot) TLocation const &NewLoc, TRotation const &NewRot)
{ {
const double Vepsilon = 1e-5; const double Vepsilon = 1e-5;
const double Aepsilon = 1e-3; // ASBSpeed=0.8; const double Aepsilon = 1e-3; // ASBSpeed=0.8;
@@ -1105,9 +1182,6 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
// TODO: investigate, seems supplied NewRot is always 0 although the code here suggests some actual values are expected // TODO: investigate, seems supplied NewRot is always 0 although the code here suggests some actual values are expected
Loc = NewLoc; Loc = NewLoc;
Rot = NewRot; Rot = NewRot;
NewRot.Rx = 0;
NewRot.Ry = 0;
NewRot.Rz = 0;
if (dL == 0) // oblicz przesuniecie} if (dL == 0) // oblicz przesuniecie}
{ {
@@ -1236,17 +1310,14 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
// ************************************************************************************************* // *************************************************************************************************
double TMoverParameters::FastComputeMovement(double dt, const TTrackShape &Shape, double TMoverParameters::FastComputeMovement(double dt, const TTrackShape &Shape,
TTrackParam &Track, const TLocation &NewLoc, TTrackParam &Track, TLocation const &NewLoc,
TRotation &NewRot) TRotation const &NewRot)
{ {
int b; int b;
// T_MoverParameters::FastComputeMovement(dt, Shape, Track, NewLoc, NewRot); // T_MoverParameters::FastComputeMovement(dt, Shape, Track, NewLoc, NewRot);
Loc = NewLoc; Loc = NewLoc;
Rot = NewRot; Rot = NewRot;
NewRot.Rx = 0.0;
NewRot.Ry = 0.0;
NewRot.Rz = 0.0;
if (dL == 0) // oblicz przesuniecie if (dL == 0) // oblicz przesuniecie
{ {
@@ -1315,10 +1386,11 @@ void TMoverParameters::compute_movement_( double const Deltatime ) {
RunInternalCommand(); RunInternalCommand();
// automatyczny rozruch // automatyczny rozruch
if (EngineType == TEngineType::ElectricSeriesMotor) if( EngineType == TEngineType::ElectricSeriesMotor ) {
if( AutoRelayCheck() ) {
if (AutoRelayCheck()) SetFlag( SoundFlag, sound::relay );
SetFlag(SoundFlag, sound::relay); }
}
if( ( EngineType == TEngineType::DieselEngine ) if( ( EngineType == TEngineType::DieselEngine )
|| ( EngineType == TEngineType::DieselElectric ) ) { || ( EngineType == TEngineType::DieselElectric ) ) {
@@ -1330,6 +1402,8 @@ void TMoverParameters::compute_movement_( double const Deltatime ) {
// TODO: gather and move current calculations to dedicated method // TODO: gather and move current calculations to dedicated method
TotalCurrent = 0; TotalCurrent = 0;
// main circuit
MainsCheck( Deltatime );
// traction motors // traction motors
MotorBlowersCheck( Deltatime ); MotorBlowersCheck( Deltatime );
// uklady hamulcowe: // uklady hamulcowe:
@@ -1371,6 +1445,37 @@ void TMoverParameters::compute_movement_( double const Deltatime ) {
PowerCouplersCheck( Deltatime ); PowerCouplersCheck( Deltatime );
} }
void TMoverParameters::MainsCheck( double const Deltatime ) {
// TODO: move other main circuit checks here
if( MainsInitTime == 0.0 ) { return; }
if( MainsInitTimeCountdown > 0.0 ) {
MainsInitTimeCountdown -= Deltatime;
}
// TBD, TODO: move voltage calculation to separate method and use also in power coupler state calculation?
auto localvoltage { 0.0 };
switch( EnginePowerSource.SourceType ) {
case TPowerSource::CurrentCollector: {
localvoltage =
std::max(
localvoltage,
std::max(
PantFrontVolt,
PantRearVolt ) );
break;
}
default: {
break;
}
}
if( ( localvoltage == 0.0 )
&& ( GetTrainsetVoltage() == 0 ) ) {
MainsInitTimeCountdown = MainsInitTime;
}
}
void TMoverParameters::PowerCouplersCheck( double const Deltatime ) { void TMoverParameters::PowerCouplersCheck( double const Deltatime ) {
// TODO: add support for other power sources // TODO: add support for other power sources
auto localvoltage { 0.0 }; auto localvoltage { 0.0 };
@@ -1382,7 +1487,13 @@ void TMoverParameters::PowerCouplersCheck( double const Deltatime ) {
break; break;
} }
case TPowerSource::Main: { case TPowerSource::Main: {
localvoltage = ( true == Mains ? Voltage : 0.0 ); // HACK: main circuit can be fed through couplers, so we explicitly check pantograph supply here
localvoltage = (
true == Mains ?
std::max(
PantFrontVolt,
PantRearVolt ) :
0.0 );
break; break;
} }
default: { default: {
@@ -1544,6 +1655,8 @@ void TMoverParameters::HeatingCheck( double const Timestep ) {
auto const absrevolutions { std::abs( generator.revolutions ) }; auto const absrevolutions { std::abs( generator.revolutions ) };
generator.voltage = ( generator.voltage = (
false == HeatingAllow ? 0.0 :
// TODO: add support for desired voltage selector
absrevolutions < generator.revolutions_min ? generator.voltage_min * absrevolutions / generator.revolutions_min : absrevolutions < generator.revolutions_min ? generator.voltage_min * absrevolutions / generator.revolutions_min :
// absrevolutions > generator.revolutions_max ? generator.voltage_max * absrevolutions / generator.revolutions_max : // absrevolutions > generator.revolutions_max ? generator.voltage_max * absrevolutions / generator.revolutions_max :
interpolate( interpolate(
@@ -1680,7 +1793,7 @@ void TMoverParameters::OilPumpCheck( double const Timestep ) {
OilPump.pressure = OilPump.pressure =
std::max<float>( std::max<float>(
OilPump.pressure_target, OilPump.pressure_target,
OilPump.pressure - 0.01 * Timestep ); OilPump.pressure - ( enrot > 5.0 ? 0.05 : 0.035 ) * 0.5 * Timestep );
} }
OilPump.pressure = clamp( OilPump.pressure, 0.f, 1.5f ); OilPump.pressure = clamp( OilPump.pressure, 0.f, 1.5f );
} }
@@ -2115,14 +2228,14 @@ bool TMoverParameters::IncScndCtrl(int CtrlSpeed)
SendCtrlToNext("SpeedCntrl", SpeedCtrlValue, CabNo); SendCtrlToNext("SpeedCntrl", SpeedCtrlValue, CabNo);
} }
if ((OK) && (SpeedCtrl) && (ScndCtrlPos == 1) && (EngineType == TEngineType::DieselEngine)) if ((OK) && (SpeedCtrl) && (ScndCtrlPos == 1) && (EngineType == TEngineType::DieselEngine))
{ {
// 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?
SpeedCtrlValue = Round(Vel); SpeedCtrlValue = Round(Vel);
SpeedCtrlUnit.IsActive = true; SpeedCtrlUnit.IsActive = true;
} }
return OK; return OK;
} }
// ************************************************************************************************* // *************************************************************************************************
@@ -2177,14 +2290,13 @@ bool TMoverParameters::DecScndCtrl(int CtrlSpeed)
SpeedCtrlUnit.IsActive = false; SpeedCtrlUnit.IsActive = false;
} }
if ((OK) && (SpeedCtrl) && (ScndCtrlPos == 0) && (EngineType == TEngineType::DieselEngine)) if ((OK) && (SpeedCtrl) && (ScndCtrlPos == 0) && (EngineType == TEngineType::DieselEngine))
{ {
// NOTE: round() already adds 0.5, are the ones added here as well correct?
SpeedCtrlValue = 0; SpeedCtrlValue = 0;
SpeedCtrlUnit.IsActive = false; SpeedCtrlUnit.IsActive = false;
} }
return OK; return OK;
} }
// ************************************************************************************************* // *************************************************************************************************
@@ -2220,7 +2332,7 @@ bool TMoverParameters::CabDeactivisation(void)
CabNo = 0; CabNo = 0;
DirAbsolute = ActiveDir * CabNo; DirAbsolute = ActiveDir * CabNo;
DepartureSignal = false; // nie buczeć z nieaktywnej kabiny DepartureSignal = false; // nie buczeć z nieaktywnej kabiny
SecuritySystem.Status = 0; // deactivate alerter TODO: make it part of control based cab selection SecuritySystem.Status = s_off; // deactivate alerter TODO: make it part of control based cab selection
SendCtrlToNext("CabActivisation", 0, ActiveCab); // CabNo==0! SendCtrlToNext("CabActivisation", 0, ActiveCab); // CabNo==0!
} }
@@ -2439,8 +2551,9 @@ void TMoverParameters::SecuritySystemCheck(double dt)
if ((!Radio)) if ((!Radio))
RadiostopSwitch(false); RadiostopSwitch(false);
if ((SecuritySystem.SystemType > 0) && (SecuritySystem.Status > 0) && if ((SecuritySystem.SystemType > 0)
(Battery)) // Ra: EZT ma teraz czuwak w rozrządczym && (SecuritySystem.Status != s_off)
&& (Battery)) // Ra: EZT ma teraz czuwak w rozrządczym
{ {
// CA // CA
if( ( SecuritySystem.AwareMinSpeed > 0.0 ? if( ( SecuritySystem.AwareMinSpeed > 0.0 ?
@@ -2468,30 +2581,29 @@ void TMoverParameters::SecuritySystemCheck(double dt)
SecuritySystem.EmergencyBrakeDelay) && SecuritySystem.EmergencyBrakeDelay) &&
(SecuritySystem.EmergencyBrakeDelay >= 0)) (SecuritySystem.EmergencyBrakeDelay >= 0))
SetFlag(SecuritySystem.Status, s_CAebrake); SetFlag(SecuritySystem.Status, s_CAebrake);
}
// SHP // SHP
if (TestFlag(SecuritySystem.SystemType, 2) && if( TestFlag( SecuritySystem.SystemType, 2 ) ) {
TestFlag(SecuritySystem.Status, s_active)) // jeśli świeci albo miga if( TestFlag( SecuritySystem.Status, s_SHPalarm ) ) {
SecuritySystem.SystemSoundSHPTimer += dt; // jeśli buczy
if (TestFlag(SecuritySystem.SystemType, 2) &&
TestFlag(SecuritySystem.Status, s_SHPalarm)) // jeśli buczy
SecuritySystem.SystemBrakeSHPTimer += dt; SecuritySystem.SystemBrakeSHPTimer += dt;
if (TestFlag(SecuritySystem.SystemType, 2) && TestFlag(SecuritySystem.Status, s_active)) }
if ((Vel > SecuritySystem.VelocityAllowed) && (SecuritySystem.VelocityAllowed >= 0)) if( TestFlag( SecuritySystem.Status, s_active ) ) {
SetFlag(SecuritySystem.Status, s_SHPebrake); // jeśli świeci albo miga
else if (((SecuritySystem.SystemSoundSHPTimer > SecuritySystem.SoundSignalDelay) && SecuritySystem.SystemSoundSHPTimer += dt;
(SecuritySystem.SoundSignalDelay >= 0)) ||
((Vel > SecuritySystem.NextVelocityAllowed) &&
(SecuritySystem.NextVelocityAllowed >= 0)))
if (!SetFlag(SecuritySystem.Status,
s_SHPalarm)) // juz wlaczony sygnal dzwiekowy}
if ((SecuritySystem.SystemBrakeSHPTimer >
SecuritySystem.EmergencyBrakeDelay) &&
(SecuritySystem.EmergencyBrakeDelay >= 0))
SetFlag(SecuritySystem.Status, s_SHPebrake);
} // else SystemTimer:=0;
if( ( SecuritySystem.VelocityAllowed >= 0 ) && ( Vel > SecuritySystem.VelocityAllowed ) ) {
SetFlag( SecuritySystem.Status, s_SHPebrake );
}
else if( ( ( SecuritySystem.SoundSignalDelay >= 0 ) && ( SecuritySystem.SystemSoundSHPTimer > SecuritySystem.SoundSignalDelay ) )
|| ( ( SecuritySystem.NextVelocityAllowed >= 0 ) && ( Vel > SecuritySystem.NextVelocityAllowed ) ) ) {
SetFlag( SecuritySystem.Status, s_SHPalarm );
if( ( SecuritySystem.EmergencyBrakeDelay >= 0 ) && ( SecuritySystem.SystemBrakeSHPTimer > SecuritySystem.EmergencyBrakeDelay ) ) {
SetFlag( SecuritySystem.Status, s_SHPebrake );
}
}
}
}
// TEST CA // TEST CA
if (TestFlag(SecuritySystem.Status, s_CAtest)) // jeśli świeci albo miga if (TestFlag(SecuritySystem.Status, s_CAtest)) // jeśli świeci albo miga
SecuritySystem.SystemBrakeCATestTimer += dt; SecuritySystem.SystemBrakeCATestTimer += dt;
@@ -2531,8 +2643,8 @@ bool TMoverParameters::BatterySwitch(bool State)
SendCtrlToNext("BatterySwitch", 0, CabNo); SendCtrlToNext("BatterySwitch", 0, CabNo);
BS = true; BS = true;
if ((Battery) && (ActiveCab != 0)) /*|| (TrainType==dt_EZT)*/ if ((Battery) && (ActiveCab != 0))
SecuritySystem.Status = (SecuritySystem.Status | s_waiting); // aktywacja czuwaka SecuritySystem.Status |= s_waiting; // aktywacja czuwaka
else else
SecuritySystem.Status = 0; // wyłączenie czuwaka SecuritySystem.Status = 0; // wyłączenie czuwaka
@@ -2999,6 +3111,7 @@ void TMoverParameters::MainSwitch_( bool const State ) {
if( ( false == State ) if( ( false == State )
|| ( ( ( ScndCtrlPos == 0 ) || ( EngineType == TEngineType::ElectricInductionMotor ) ) || ( ( ( ScndCtrlPos == 0 ) || ( EngineType == TEngineType::ElectricInductionMotor ) )
&& ( ( ConvOvldFlag == false ) || ( TrainType == dt_EZT ) ) && ( ( ConvOvldFlag == false ) || ( TrainType == dt_EZT ) )
&& ( MainsInitTimeCountdown <= 0.0 )
&& ( true == NoVoltRelay ) && ( true == NoVoltRelay )
&& ( true == OvervoltageRelay ) && ( true == OvervoltageRelay )
&& ( LastSwitchingTime > CtrlDelay ) && ( LastSwitchingTime > CtrlDelay )
@@ -4228,7 +4341,6 @@ void TMoverParameters::ComputeConstans(void)
double BearingF, RollF, HideModifier; double BearingF, RollF, HideModifier;
double Curvature; // Ra 2014-07: odwrotność promienia double Curvature; // Ra 2014-07: odwrotność promienia
TotalMass = ComputeMass();
TotalMassxg = TotalMass * g; // TotalMass*g TotalMassxg = TotalMass * g; // TotalMass*g
BearingF = 2.0 * (DamageFlag && dtrain_bearing); BearingF = 2.0 * (DamageFlag && dtrain_bearing);
@@ -4279,29 +4391,28 @@ void TMoverParameters::ComputeConstans(void)
// Q: 20160713 // Q: 20160713
// Oblicza masę ładunku // Oblicza masę ładunku
// ************************************************************************************************* // *************************************************************************************************
double TMoverParameters::ComputeMass(void) void TMoverParameters::ComputeMass()
{ {
double M { 0.0 };
// TODO: unit weight table, pulled from external data file
if( LoadAmount > 0 ) {
if (ToLower(LoadQuantity) == "tonns")
M = LoadAmount * 1000;
else if (LoadType.name == "passengers")
M = LoadAmount * 80;
else if (LoadType.name == "luggage")
M = LoadAmount * 100;
else if (LoadType.name == "cars")
M = LoadAmount * 1200; // 800 kilo to miał maluch
else if (LoadType.name == "containers")
M = LoadAmount * 8000;
else if (LoadType.name == "transformers")
M = LoadAmount * 50000;
else
M = LoadAmount * 1000;
}
// Ra: na razie tak, ale nie wszędzie masy wirujące się wliczają // Ra: na razie tak, ale nie wszędzie masy wirujące się wliczają
return Mass + M + Mred; TotalMass = Mass + Mred;
if( LoadAmount == 0 ) { return; }
// include weight of carried load
auto loadtypeunitweight { 0.f };
if( ToLower( LoadQuantity ) == "tonns" ) {
loadtypeunitweight = 1000;
}
else {
auto const lookup { simulation::Weights.find( LoadType.name ) };
loadtypeunitweight = (
lookup != simulation::Weights.end() ?
lookup->second :
1000.f ); // legacy default unit weight value
}
TotalMass += LoadAmount * loadtypeunitweight;
} }
// ************************************************************************************************* // *************************************************************************************************
@@ -4343,6 +4454,11 @@ void TMoverParameters::ComputeTotalForce(double dt) {
// juz zoptymalizowane: // juz zoptymalizowane:
FStand = FrictionForce(RunningShape.R, RunningTrack.DamageFlag); // siła oporów ruchu FStand = FrictionForce(RunningShape.R, RunningTrack.DamageFlag); // siła oporów ruchu
if( true == TestFlag( DamageFlag, dtrain_out ) ) {
// HACK: crude way to reduce speed after derailment
// TBD, TODO: more accurate approach?
FStand *= 1e20;
}
double old_nrot = abs(nrot); double old_nrot = abs(nrot);
nrot = v2n(); // przeliczenie prędkości liniowej na obrotową nrot = v2n(); // przeliczenie prędkości liniowej na obrotową
@@ -4635,15 +4751,13 @@ double TMoverParameters::CouplerForce( int const End, double dt ) {
auto &othercoupler { othervehicle->Couplers[ otherend ] }; auto &othercoupler { othervehicle->Couplers[ otherend ] };
auto const othervehiclemove { ( othervehicle->dMoveLen * DirPatch( End, otherend ) ) }; auto const othervehiclemove { ( othervehicle->dMoveLen * DirPatch( End, otherend ) ) };
auto const initialdistance { Neighbours[ End ].distance }; // odległość od sprzęgu sąsiada
auto const distancedelta { ( auto const distancedelta { (
End == end::front ? End == end::front ?
othervehiclemove - dMoveLen : othervehiclemove - dMoveLen :
dMoveLen - othervehiclemove ) }; dMoveLen - othervehiclemove ) };
auto const initialdistance { Neighbours[ End ].distance }; // odległość od sprzęgu sąsiada
auto const newdistance = auto const newdistance { initialdistance + 10.0 * distancedelta };
initialdistance
+ 10.0 * distancedelta;
auto const dV { V - ( othervehicle->V * DirPatch( End, otherend ) ) }; auto const dV { V - ( othervehicle->V * DirPatch( End, otherend ) ) };
auto const absdV { std::abs( dV ) }; auto const absdV { std::abs( dV ) };
@@ -4673,11 +4787,15 @@ double TMoverParameters::CouplerForce( int const End, double dt ) {
} }
coupler.CheckCollision = false; coupler.CheckCollision = false;
coupler.Dist = 0.0;
double CF { 0.0 }; double CF { 0.0 };
if( ( coupler.CouplingFlag != coupling::faux ) if( ( coupler.CouplingFlag != coupling::faux )
|| ( initialdistance < 0 ) ) { || ( initialdistance < 0 ) ) {
coupler.Dist = clamp( newdistance, -coupler.DmaxB, coupler.DmaxC );
double BetaAvg = 0; double BetaAvg = 0;
double Fmax = 0; double Fmax = 0;
@@ -4692,8 +4810,8 @@ double TMoverParameters::CouplerForce( int const End, double dt ) {
Fmax = 0.5 * ( coupler.FmaxC + coupler.FmaxB + othercoupler.FmaxC + othercoupler.FmaxB ) * CouplerTune; Fmax = 0.5 * ( coupler.FmaxC + coupler.FmaxB + othercoupler.FmaxC + othercoupler.FmaxB ) * CouplerTune;
} }
auto const distDelta { std::abs( newdistance ) - std::abs( coupler.Dist ) }; // McZapkie-191103: poprawka na histereze auto const distDelta { std::abs( newdistance ) - std::abs( coupler.Dist ) }; // McZapkie-191103: poprawka na histereze
coupler.Dist = newdistance;
if (coupler.Dist > 0) { if (newdistance > 0) {
if( distDelta > 0 ) { if( distDelta > 0 ) {
CF = ( -( coupler.SpringKC + othercoupler.SpringKC ) * coupler.Dist / 2.0 ) * DirF( End ) CF = ( -( coupler.SpringKC + othercoupler.SpringKC ) * coupler.Dist / 2.0 ) * DirF( End )
@@ -4704,12 +4822,25 @@ double TMoverParameters::CouplerForce( int const End, double dt ) {
- Fmax * dV * BetaAvg; - Fmax * dV * BetaAvg;
} }
// liczenie sily ze sprezystosci sprzegu // liczenie sily ze sprezystosci sprzegu
if( coupler.Dist > ( coupler.DmaxC + othercoupler.DmaxC ) ) { if( newdistance > ( coupler.DmaxC + othercoupler.DmaxC ) ) {
// zderzenie // zderzenie
coupler.CheckCollision = true; coupler.CheckCollision = true;
} }
if( std::abs( CF ) > coupler.FmaxC ) {
// coupler is stretched with excessive force, may break
coupler.stretch_duration += dt;
// give coupler 1 sec of leeway to account for simulation glitches, before checking whether it breaks
// (arbitrary) chance to break grows from 10-100% over 10 sec period
if( ( coupler.stretch_duration > 1.f )
&& ( Random() < ( coupler.stretch_duration * 0.1f * dt ) ) ) {
damage_coupler( End );
}
}
else {
coupler.stretch_duration = 0.f;
}
} }
if( coupler.Dist < 0 ) { if( newdistance < 0 ) {
if( distDelta > 0 ) { if( distDelta > 0 ) {
CF = ( -( coupler.SpringKB + othercoupler.SpringKB ) * coupler.Dist / 2.0 ) * DirF( End ) CF = ( -( coupler.SpringKB + othercoupler.SpringKB ) * coupler.Dist / 2.0 ) * DirF( End )
@@ -4720,7 +4851,7 @@ double TMoverParameters::CouplerForce( int const End, double dt ) {
- Fmax * dV * BetaAvg; - Fmax * dV * BetaAvg;
} }
// liczenie sily ze sprezystosci zderzaka // liczenie sily ze sprezystosci zderzaka
if( -coupler.Dist > ( coupler.DmaxB + othercoupler.DmaxB ) ) { if( -newdistance > ( coupler.DmaxB + othercoupler.DmaxB ) ) {
// zderzenie // zderzenie
coupler.CheckCollision = true; coupler.CheckCollision = true;
if( ( coupler.CouplerType == TCouplerType::Automatic ) if( ( coupler.CouplerType == TCouplerType::Automatic )
@@ -4774,9 +4905,12 @@ double TMoverParameters::TractionForce( double dt ) {
EngineHeatingRPM ) EngineHeatingRPM )
/ 60.0 ); / 60.0 );
} }
// NOTE: fake dizel_fill calculation for the sake of smoke emitter which uses this parameter to determine smoke opacity
dizel_fill = clamp( 0.2 + 0.35 * ( tmp - enrot ), 0.0, 1.0 );
} }
else { else {
tmp = 0.0; tmp = 0.0;
dizel_fill = 0.0;
} }
if( enrot != tmp ) { if( enrot != tmp ) {
@@ -5523,12 +5657,12 @@ double TMoverParameters::TractionForce( double dt ) {
eimv[eimv_Fzad] = PosRatio; eimv[eimv_Fzad] = PosRatio;
if ((Flat) && (eimc[eimc_p_F0] * eimv[eimv_Fful] > 0)) if ((Flat) && (eimc[eimc_p_F0] * eimv[eimv_Fful] > 0))
PosRatio = Min0R(PosRatio * eimc[eimc_p_F0] / eimv[eimv_Fful], 1); PosRatio = Min0R(PosRatio * eimc[eimc_p_F0] / eimv[eimv_Fful], 1);
/* if (SpeedCtrlValue > 0) //speed control /* if (ScndCtrlActualPos > 0) //speed control
if (Vmax < 250) if (Vmax < 250)
PosRatio = Min0R(PosRatio, Max0R(-1, 0.5 * (SpeedCtrlValue - Vel))); PosRatio = Min0R(PosRatio, Max0R(-1, 0.5 * (ScndCtrlActualPos - Vel)));
else else
PosRatio = PosRatio =
Min0R(PosRatio, Max0R(-1, 0.5 * (SpeedCtrlValue * 2 - Vel))); */ Min0R(PosRatio, Max0R(-1, 0.5 * (ScndCtrlActualPos * 2 - Vel))); */
// PosRatio = 1.0 * (PosRatio * 0 + 1) * PosRatio; // 1 * 1 * PosRatio = PosRatio // PosRatio = 1.0 * (PosRatio * 0 + 1) * PosRatio; // 1 * 1 * PosRatio = PosRatio
Hamulec->SetED(0); Hamulec->SetED(0);
// (Hamulec as TLSt).SetLBP(LocBrakePress); // (Hamulec as TLSt).SetLBP(LocBrakePress);
@@ -5616,25 +5750,19 @@ double TMoverParameters::TractionForce( double dt ) {
eimv[eimv_ks] = eimv[eimv_Fr] / eimv[eimv_FMAXMAX]; eimv[eimv_ks] = eimv[eimv_Fr] / eimv[eimv_FMAXMAX];
eimv[eimv_df] = eimv[eimv_ks] * eimc[eimc_s_dfmax]; eimv[eimv_df] = eimv[eimv_ks] * eimc[eimc_s_dfmax];
eimv[eimv_fp] = DirAbsolute * enrot * eimc[eimc_s_p] + eimv[eimv_fp] = DirAbsolute * enrot * eimc[eimc_s_p] + eimv[eimv_df]; // do przemyslenia dzialanie pp z tmpV
eimv[eimv_df]; // do przemyslenia dzialanie pp z tmpV
// eimv[eimv_U]:=Max0R(eimv[eimv_Uzsmax],Min0R(eimc[eimc_f_cfu]*eimv[eimv_fp],eimv[eimv_Uzsmax])); // eimv[eimv_U]:=Max0R(eimv[eimv_Uzsmax],Min0R(eimc[eimc_f_cfu]*eimv[eimv_fp],eimv[eimv_Uzsmax]));
// eimv[eimv_pole]:=eimv[eimv_U]/(eimv[eimv_fp]*eimc[eimc_s_cfu]); // eimv[eimv_pole]:=eimv[eimv_U]/(eimv[eimv_fp]*eimc[eimc_s_cfu]);
if ((abs(eimv[eimv_fp]) <= eimv[eimv_fkr])) if ((abs(eimv[eimv_fp]) <= eimv[eimv_fkr]))
eimv[eimv_pole] = eimc[eimc_f_cfu] / eimc[eimc_s_cfu]; eimv[eimv_pole] = eimc[eimc_f_cfu] / eimc[eimc_s_cfu];
else else
eimv[eimv_pole] = eimv[eimv_pole] = eimv[eimv_Uzsmax] / eimc[eimc_s_cfu] / abs(eimv[eimv_fp]);
eimv[eimv_Uzsmax] / eimc[eimc_s_cfu] / abs(eimv[eimv_fp]);
eimv[eimv_U] = eimv[eimv_pole] * eimv[eimv_fp] * eimc[eimc_s_cfu]; eimv[eimv_U] = eimv[eimv_pole] * eimv[eimv_fp] * eimc[eimc_s_cfu];
eimv[eimv_Ic] = (eimv[eimv_fp] - DirAbsolute * enrot * eimc[eimc_s_p]) * eimv[eimv_Ic] = (eimv[eimv_fp] - DirAbsolute * enrot * eimc[eimc_s_p]) * eimc[eimc_s_dfic] * eimv[eimv_pole];
eimc[eimc_s_dfic] * eimv[eimv_pole];
eimv[eimv_If] = eimv[eimv_Ic] * eimc[eimc_s_icif]; eimv[eimv_If] = eimv[eimv_Ic] * eimc[eimc_s_icif];
eimv[eimv_M] = eimv[eimv_pole] * eimv[eimv_Ic] * eimc[eimc_s_cim]; eimv[eimv_M] = eimv[eimv_pole] * eimv[eimv_Ic] * eimc[eimc_s_cim];
eimv[eimv_Ipoj] = (eimv[eimv_Ic] * NPoweredAxles * eimv[eimv_U]) / eimv[eimv_Ipoj] = (eimv[eimv_Ic] * NPoweredAxles * eimv[eimv_U]) / (Voltage - eimc[eimc_f_DU]) + eimc[eimc_f_I0];
(Voltage - eimc[eimc_f_DU]) + eimv[eimv_Pm] = ActiveDir * eimv[eimv_M] * NPoweredAxles * enrot * Pirazy2 / 1000;
eimc[eimc_f_I0];
eimv[eimv_Pm] =
ActiveDir * eimv[eimv_M] * NPoweredAxles * enrot * Pirazy2 / 1000;
eimv[eimv_Pe] = eimv[eimv_Ipoj] * Voltage / 1000; eimv[eimv_Pe] = eimv[eimv_Ipoj] * Voltage / 1000;
eimv[eimv_eta] = eimv[eimv_Pm] / eimv[eimv_Pe]; eimv[eimv_eta] = eimv[eimv_Pm] / eimv[eimv_Pe];
@@ -5655,7 +5783,7 @@ double TMoverParameters::TractionForce( double dt ) {
if( ( RlistSize > 0 ) if( ( RlistSize > 0 )
&& ( ( std::abs( eimv[ eimv_If ] ) > 1.0 ) && ( ( std::abs( eimv[ eimv_If ] ) > 1.0 )
|| ( tmpV > 0.1 ) ) ) { && ( tmpV > 0.1 ) ) ) {
int i = 0; int i = 0;
while( ( i < RlistSize - 1 ) while( ( i < RlistSize - 1 )
@@ -7386,6 +7514,7 @@ TMoverParameters::AssignLoad( std::string const &Name, float const Amount ) {
if( Name == loadattributes.name ) { if( Name == loadattributes.name ) {
LoadType = loadattributes; LoadType = loadattributes;
LoadAmount = clamp( Amount, 0.f, MaxLoad ) ; LoadAmount = clamp( Amount, 0.f, MaxLoad ) ;
ComputeMass();
return true; return true;
} }
} }
@@ -7405,7 +7534,7 @@ bool TMoverParameters::LoadingDone(double const LSpeed, std::string const &Loadn
return true; return true;
} }
if( Loadname.empty() ) { return ( LoadStatus >= 4 ); } if( Loadname.empty() ) { return ( LoadStatus >= 4 ); }
if( Loadname != LoadType.name ) { return ( LoadStatus >= 4 ); } if( Loadname != LoadType.name ) { return ( LoadStatus >= 4 ); }
// test zakończenia załadunku/rozładunku // test zakończenia załadunku/rozładunku
@@ -7428,6 +7557,7 @@ bool TMoverParameters::LoadingDone(double const LSpeed, std::string const &Loadn
if( LoadAmount == 0.f ) { if( LoadAmount == 0.f ) {
AssignLoad(""); // jak nic nie ma, to nie ma też nazwy AssignLoad(""); // jak nic nie ma, to nie ma też nazwy
} }
ComputeMass();
} }
} }
else if( LSpeed > 0 ) { else if( LSpeed > 0 ) {
@@ -7442,6 +7572,7 @@ bool TMoverParameters::LoadingDone(double const LSpeed, std::string const &Loadn
LoadStatus = 4; // skończony załadunek LoadStatus = 4; // skończony załadunek
LoadAmount = std::min<float>( MaxLoad * ( 1.0 + OverLoadFactor ), LoadAmount ); LoadAmount = std::min<float>( MaxLoad * ( 1.0 + OverLoadFactor ), LoadAmount );
} }
ComputeMass();
} }
} }
@@ -8614,7 +8745,7 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
continue; continue;
} }
if (issection("SpeedControl:", inputline)) if (issection("SpeedControl:", inputline))
{ {
startBPT = false; startBPT = false;
fizlines.emplace("SpeedControl", inputline); fizlines.emplace("SpeedControl", inputline);
@@ -8622,7 +8753,7 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
continue; continue;
} }
if( issection( "Engine:", inputline ) ) if( issection( "Engine:", inputline ) )
{ {
startBPT = false; startBPT = false;
fizlines.emplace( "Engine", inputline ); fizlines.emplace( "Engine", inputline );
@@ -9373,6 +9504,8 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
extract_value( StopBrakeDecc, "SBD", line, "" ); extract_value( StopBrakeDecc, "SBD", line, "" );
// main circuit
extract_value( MainsInitTime, "MainInitTime", line, "" );
// converter // converter
{ {
std::map<std::string, start_t> starts { std::map<std::string, start_t> starts {
@@ -10767,10 +10900,13 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
Battery = true; Battery = true;
else if ((CValue1 == 0)) else if ((CValue1 == 0))
Battery = false; Battery = false;
if ((Battery) && (ActiveCab != 0) /*or (TrainType=dt_EZT)*/) /*
SecuritySystem.Status = SecuritySystem.Status || s_waiting; // aktywacja czuwaka // TBD: makes no sense to activate alerters in entire consist
if ((Battery) && (ActiveCab != 0) )
SecuritySystem.Status = SecuritySystem.Status | s_waiting; // aktywacja czuwaka
else else
SecuritySystem.Status = 0; // wyłączenie czuwaka SecuritySystem.Status = 0; // wyłączenie czuwaka
*/
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype ); OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
} }
// else if command='EpFuseSwitch' then {NBMX} // else if command='EpFuseSwitch' then {NBMX}
@@ -11138,3 +11274,9 @@ double TMoverParameters::ShowCurrentP(int AmpN) const
return current; return current;
} }
} }
namespace simulation {
weights_table Weights;
} // simulation

600
Train.cpp

File diff suppressed because it is too large Load Diff

34
Train.h
View File

@@ -69,8 +69,10 @@ public:
find( TSubModel const *Control ) const; find( TSubModel const *Control ) const;
}; };
class TTrain class TTrain {
{
friend class drivingaid_panel;
public: public:
// types // types
struct state_t { struct state_t {
@@ -88,6 +90,7 @@ class TTrain
std::uint8_t ventilator_overload; std::uint8_t ventilator_overload;
std::uint8_t motor_overload_threshold; std::uint8_t motor_overload_threshold;
std::uint8_t train_heating; std::uint8_t train_heating;
std::uint8_t cab;
std::uint8_t recorder_braking; std::uint8_t recorder_braking;
std::uint8_t recorder_power; std::uint8_t recorder_power;
std::uint8_t alerter_sound; std::uint8_t alerter_sound;
@@ -98,13 +101,15 @@ class TTrain
float brake_pressure; float brake_pressure;
float hv_voltage; float hv_voltage;
std::array<float, 3> hv_current; std::array<float, 3> hv_current;
float lv_voltage;
}; };
// constructors
TTrain();
// methods // methods
bool CabChange(int iDirection); bool CabChange(int iDirection);
bool ShowNextCurrent; // pokaz przd w podlaczonej lokomotywie (ET41) bool ShowNextCurrent; // pokaz przd w podlaczonej lokomotywie (ET41)
bool InitializeCab(int NewCabNo, std::string const &asFileName); bool InitializeCab(int NewCabNo, std::string const &asFileName);
TTrain();
// McZapkie-010302 // McZapkie-010302
bool Init(TDynamicObject *NewDynamicObject, bool e3d = false); bool Init(TDynamicObject *NewDynamicObject, bool e3d = false);
@@ -113,6 +118,7 @@ class TTrain
inline std::string GetLabel( TSubModel const *Control ) const { return m_controlmapper.find( Control ); } inline std::string GetLabel( TSubModel const *Control ) const { return m_controlmapper.find( Control ); }
void UpdateCab(); void UpdateCab();
bool Update( double const Deltatime ); bool Update( double const Deltatime );
void add_distance( double const Distance );
void SetLights(); void SetLights();
// McZapkie-310302: ladowanie parametrow z pliku // McZapkie-310302: ladowanie parametrow z pliku
bool LoadMMediaFile(std::string const &asFileName); bool LoadMMediaFile(std::string const &asFileName);
@@ -151,6 +157,12 @@ class TTrain
void update_sounds( double const Deltatime ); void update_sounds( double const Deltatime );
void update_sounds_runningnoise( sound_source &Sound ); void update_sounds_runningnoise( sound_source &Sound );
void update_sounds_radio(); void update_sounds_radio();
inline
end cab_to_end() const {
return (
iCabn == 2 ?
end::rear :
end::front ); }
// command handlers // command handlers
// NOTE: we're currently using universal handlers and static handler map but it may be beneficial to have these implemented on individual class instance basis // NOTE: we're currently using universal handlers and static handler map but it may be beneficial to have these implemented on individual class instance basis
@@ -350,6 +362,7 @@ class TTrain
static void OnCommand_radiochanneldecrease( TTrain *Train, command_data const &Command ); static void OnCommand_radiochanneldecrease( TTrain *Train, command_data const &Command );
static void OnCommand_radiostopsend( TTrain *Train, command_data const &Command ); static void OnCommand_radiostopsend( TTrain *Train, command_data const &Command );
static void OnCommand_radiostoptest( TTrain *Train, command_data const &Command ); static void OnCommand_radiostoptest( TTrain *Train, command_data const &Command );
static void OnCommand_radiocall3send( TTrain *Train, command_data const &Command );
static void OnCommand_cabchangeforward( TTrain *Train, command_data const &Command ); static void OnCommand_cabchangeforward( TTrain *Train, command_data const &Command );
static void OnCommand_cabchangebackward( TTrain *Train, command_data const &Command ); static void OnCommand_cabchangebackward( TTrain *Train, command_data const &Command );
static void OnCommand_generictoggle( TTrain *Train, command_data const &Command ); static void OnCommand_generictoggle( TTrain *Train, command_data const &Command );
@@ -360,6 +373,7 @@ class TTrain
static void OnCommand_springbrakeshutoffenable(TTrain *Train, command_data const &Command); static void OnCommand_springbrakeshutoffenable(TTrain *Train, command_data const &Command);
static void OnCommand_springbrakeshutoffdisable(TTrain *Train, command_data const &Command); static void OnCommand_springbrakeshutoffdisable(TTrain *Train, command_data const &Command);
static void OnCommand_springbrakerelease(TTrain *Train, command_data const &Command); static void OnCommand_springbrakerelease(TTrain *Train, command_data const &Command);
static void OnCommand_distancecounteractivate( TTrain *Train, command_data const &Command );
static void OnCommand_speedcontrolincrease(TTrain *Train, command_data const &Command); static void OnCommand_speedcontrolincrease(TTrain *Train, command_data const &Command);
static void OnCommand_speedcontroldecrease(TTrain *Train, command_data const &Command); static void OnCommand_speedcontroldecrease(TTrain *Train, command_data const &Command);
static void OnCommand_speedcontrolpowerincrease(TTrain *Train, command_data const &Command); static void OnCommand_speedcontrolpowerincrease(TTrain *Train, command_data const &Command);
@@ -429,7 +443,7 @@ public: // reszta może by?publiczna
TGauge ggUniveralBrakeButton2; TGauge ggUniveralBrakeButton2;
TGauge ggUniveralBrakeButton3; TGauge ggUniveralBrakeButton3;
TGauge ggSandButton; // guzik piasecznicy TGauge ggSandButton; // guzik piasecznicy
TGauge ggAutoSandAllow; // przełącznik piasecznicy TGauge ggAutoSandButton; // przełącznik piasecznicy
TGauge ggAntiSlipButton; TGauge ggAntiSlipButton;
TGauge ggFuseButton; TGauge ggFuseButton;
TGauge ggConverterFuseButton; // hunter-261211: przycisk odblokowania nadmiarowego przetwornic i ogrzewania TGauge ggConverterFuseButton; // hunter-261211: przycisk odblokowania nadmiarowego przetwornic i ogrzewania
@@ -440,6 +454,7 @@ public: // reszta może by?publiczna
TGauge ggRadioChannelNext; TGauge ggRadioChannelNext;
TGauge ggRadioTest; TGauge ggRadioTest;
TGauge ggRadioStop; TGauge ggRadioStop;
TGauge ggRadioCall3;
TGauge ggUpperLightButton; TGauge ggUpperLightButton;
TGauge ggLeftLightButton; TGauge ggLeftLightButton;
TGauge ggRightLightButton; TGauge ggRightLightButton;
@@ -472,14 +487,14 @@ public: // reszta może by?publiczna
TGauge ggHelperButton; TGauge ggHelperButton;
TGauge ggNextCurrentButton; TGauge ggNextCurrentButton;
// yB 191005 - tempomat // yB 191005 - tempomat
TGauge ggSpeedControlIncreaseButton; TGauge ggSpeedControlIncreaseButton;
TGauge ggSpeedControlDecreaseButton; TGauge ggSpeedControlDecreaseButton;
TGauge ggSpeedControlPowerIncreaseButton; TGauge ggSpeedControlPowerIncreaseButton;
TGauge ggSpeedControlPowerDecreaseButton; TGauge ggSpeedControlPowerDecreaseButton;
std::array<TGauge, 10> ggSpeedCtrlButtons; // NOTE: temporary arrangement until we have dynamically built control table std::array<TGauge, 10> ggSpeedCtrlButtons; // NOTE: temporary arrangement until we have dynamically built control table
std::array<TGauge, 10> ggUniversals; // NOTE: temporary arrangement until we have dynamically built control table std::array<TGauge, 10> ggUniversals; // NOTE: temporary arrangement until we have dynamically built control table
TGauge ggInstrumentLightButton; TGauge ggInstrumentLightButton;
TGauge ggDashboardLightButton; TGauge ggDashboardLightButton;
@@ -529,6 +544,8 @@ public: // reszta może by?publiczna
TGauge ggMotorBlowersRearButton; // rear traction motor fan switch TGauge ggMotorBlowersRearButton; // rear traction motor fan switch
TGauge ggMotorBlowersAllOffButton; // motor fans shutdown switch TGauge ggMotorBlowersAllOffButton; // motor fans shutdown switch
TGauge ggDistanceCounterButton; // distance meter activation button
TButton btLampkaPoslizg; TButton btLampkaPoslizg;
TButton btLampkaStyczn; TButton btLampkaStyczn;
TButton btLampkaNadmPrzetw; TButton btLampkaNadmPrzetw;
@@ -624,6 +641,7 @@ public: // reszta może by?publiczna
TButton btLampkaMotorBlowers; TButton btLampkaMotorBlowers;
TButton btLampkaCoolingFans; TButton btLampkaCoolingFans;
TButton btLampkaTempomat; TButton btLampkaTempomat;
TButton btLampkaDistanceCounter;
TButton btCabLight; // hunter-171012: lampa oswietlajaca kabine TButton btCabLight; // hunter-171012: lampa oswietlajaca kabine
// Ra 2013-12: wirtualne "lampki" do odbijania na haslerze w PoKeys // Ra 2013-12: wirtualne "lampki" do odbijania na haslerze w PoKeys
@@ -656,6 +674,7 @@ public: // reszta może by?publiczna
sound_source m_radiosound { sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // cached template for radio messages sound_source m_radiosound { sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // cached template for radio messages
std::vector<std::pair<int, std::shared_ptr<sound_source>>> m_radiomessages; // list of currently played radio messages std::vector<std::pair<int, std::shared_ptr<sound_source>>> m_radiomessages; // list of currently played radio messages
sound_source m_radiostop { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; sound_source m_radiostop { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
sound_source m_distancecounterclear { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // distance meter 'good to go' alert
/* /*
int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne) int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne)
bool bCabLight; // hunter-091012: czy swiatlo jest zapalone? bool bCabLight; // hunter-091012: czy swiatlo jest zapalone?
@@ -663,7 +682,7 @@ public: // reszta może by?publiczna
*/ */
// McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc // McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc
std::array<TCab, maxcab + 1> Cabine; // przedzial maszynowy, kabina 1 (A), kabina 2 (B) std::array<TCab, maxcab + 1> Cabine; // przedzial maszynowy, kabina 1 (A), kabina 2 (B)
int iCabn { 0 }; int iCabn { 0 }; // 0: mid, 1: front, 2: rear
// McZapkie: do poruszania sie po kabinie // McZapkie: do poruszania sie po kabinie
Math3D::vector3 pMechSittingPosition; // ABu 180404 Math3D::vector3 pMechSittingPosition; // ABu 180404
Math3D::vector3 MirrorPosition( bool lewe ); Math3D::vector3 MirrorPosition( bool lewe );
@@ -709,6 +728,7 @@ private:
float m_mastercontrollerreturndelay { 0.f }; float m_mastercontrollerreturndelay { 0.f };
int iRadioChannel { 1 }; // numer aktualnego kana?u radiowego int iRadioChannel { 1 }; // numer aktualnego kana?u radiowego
std::vector<std::pair<std::string, texture_handle>> m_screens; std::vector<std::pair<std::string, texture_handle>> m_screens;
float m_distancecounter { -1.f }; // distance traveled since meter was activated or -1 if inactive
public: public:
float fPress[20][3]; // cisnienia dla wszystkich czlonow float fPress[20][3]; // cisnienia dla wszystkich czlonow

View File

@@ -132,7 +132,8 @@ commanddescription_sequence Commands_descriptions = {
{ "radiochanneldecrease", command_target::vehicle }, { "radiochanneldecrease", command_target::vehicle },
{ "radiostopsend", command_target::vehicle }, { "radiostopsend", command_target::vehicle },
{ "radiostoptest", command_target::vehicle }, { "radiostoptest", command_target::vehicle },
// TBD, TODO: make cab change controls entity-centric { "radiocall3send", command_target::vehicle },
// TBD, TODO: make cab change controls entity-centric
{ "cabchangeforward", command_target::vehicle }, { "cabchangeforward", command_target::vehicle },
{ "cabchangebackward", command_target::vehicle }, { "cabchangebackward", command_target::vehicle },
@@ -244,7 +245,8 @@ commanddescription_sequence Commands_descriptions = {
{ "springbrakeshutoffenable", command_target::vehicle }, { "springbrakeshutoffenable", command_target::vehicle },
{ "springbrakeshutoffdisable", command_target::vehicle }, { "springbrakeshutoffdisable", command_target::vehicle },
{ "springbrakerelease", command_target::vehicle }, { "springbrakerelease", command_target::vehicle },
{ "speedcontrolincrease", command_target::vehicle }, { "distancecounteractivate", command_target::vehicle },
{ "speedcontrolincrease", command_target::vehicle },
{ "speedcontroldecrease", command_target::vehicle }, { "speedcontroldecrease", command_target::vehicle },
{ "speedcontrolpowerincrease", command_target::vehicle }, { "speedcontrolpowerincrease", command_target::vehicle },
{ "speedcontrolpowerdecrease", command_target::vehicle }, { "speedcontrolpowerdecrease", command_target::vehicle },

View File

@@ -126,6 +126,7 @@ enum class user_command {
radiochanneldecrease, radiochanneldecrease,
radiostopsend, radiostopsend,
radiostoptest, radiostoptest,
radiocall3send,
cabchangeforward, cabchangeforward,
cabchangebackward, cabchangebackward,
@@ -237,6 +238,7 @@ enum class user_command {
springbrakeshutoffenable, springbrakeshutoffenable,
springbrakeshutoffdisable, springbrakeshutoffdisable,
springbrakerelease, springbrakerelease,
distancecounteractivate,
speedcontrolincrease, speedcontrolincrease,
speedcontroldecrease, speedcontroldecrease,
speedcontrolpowerincrease, speedcontrolpowerincrease,