mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 08:39:18 +02:00
Merge branch 'milek-dev' into gfx-work
This commit is contained in:
87
Driver.cpp
87
Driver.cpp
@@ -180,9 +180,9 @@ TSpeedPos::TSpeedPos(TTrack *track, double dist, int flag)
|
|||||||
Set(track, dist, flag);
|
Set(track, dist, flag);
|
||||||
};
|
};
|
||||||
|
|
||||||
TSpeedPos::TSpeedPos(basic_event *event, double dist, TOrders order)
|
TSpeedPos::TSpeedPos(basic_event *event, double dist, double length, TOrders order)
|
||||||
{
|
{
|
||||||
Set(event, dist, order);
|
Set(event, dist, length, order);
|
||||||
};
|
};
|
||||||
|
|
||||||
void TSpeedPos::Clear()
|
void TSpeedPos::Clear()
|
||||||
@@ -364,13 +364,20 @@ bool TSpeedPos::IsProperSemaphor(TOrders order)
|
|||||||
return false; // true gdy zatrzymanie, wtedy nie ma po co skanować dalej
|
return false; // true gdy zatrzymanie, wtedy nie ma po co skanować dalej
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TSpeedPos::Set(basic_event *event, double dist, TOrders order)
|
bool TSpeedPos::Set(basic_event *event, double dist, double length, TOrders order)
|
||||||
{ // zapamiętanie zdarzenia
|
{ // zapamiętanie zdarzenia
|
||||||
fDist = dist;
|
fDist = dist;
|
||||||
iFlags = spEnabled | spEvent; // event+istotny
|
iFlags = spEvent;
|
||||||
evEvent = event;
|
evEvent = event;
|
||||||
vPos = event->input_location(); // współrzędne eventu albo komórki pamięci (zrzutować na tor?)
|
vPos = event->input_location(); // współrzędne eventu albo komórki pamięci (zrzutować na tor?)
|
||||||
|
if( dist + length >= 0 ) {
|
||||||
|
iFlags |= spEnabled;
|
||||||
CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości
|
CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// located behind the tracking consist, don't bother with it
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// zależnie od trybu sprawdzenie czy jest tutaj gdzieś semafor lub tarcza manewrowa
|
// zależnie od trybu sprawdzenie czy jest tutaj gdzieś semafor lub tarcza manewrowa
|
||||||
// jeśli wskazuje stop wtedy wystawiamy true jako koniec sprawdzania
|
// jeśli wskazuje stop wtedy wystawiamy true jako koniec sprawdzania
|
||||||
// WriteLog("EventSet: Vel=" + AnsiString(fVelNext) + " iFlags=" + AnsiString(iFlags) + " order="+AnsiString(order));
|
// WriteLog("EventSet: Vel=" + AnsiString(fVelNext) + " iFlags=" + AnsiString(iFlags) + " order="+AnsiString(order));
|
||||||
@@ -580,6 +587,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
|||||||
if( newspeedpoint.Set(
|
if( newspeedpoint.Set(
|
||||||
pEvent,
|
pEvent,
|
||||||
GetDistanceToEvent( pTrack, pEvent, fLastDir, fCurrentDistance ),
|
GetDistanceToEvent( pTrack, pEvent, fLastDir, fCurrentDistance ),
|
||||||
|
fLength,
|
||||||
OrderCurrentGet() ) ) {
|
OrderCurrentGet() ) ) {
|
||||||
|
|
||||||
fDistance = newspeedpoint.fDist; // jeśli sygnał stop, to nie ma potrzeby dalej skanować
|
fDistance = newspeedpoint.fDist; // jeśli sygnał stop, to nie ma potrzeby dalej skanować
|
||||||
@@ -1909,12 +1917,28 @@ void TController::AutoRewident()
|
|||||||
mvOccupied->BrakeOpModeFlag = i;
|
mvOccupied->BrakeOpModeFlag = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// teraz zerujemy tabelkę opóźnienia hamowania
|
// teraz zerujemy tabelkę opóźnienia hamowania
|
||||||
for (int i = 0; i < BrakeAccTableSize; ++i)
|
for (int i = 0; i < BrakeAccTableSize; ++i)
|
||||||
{
|
{
|
||||||
fBrake_a0[i+1] = 0;
|
fBrake_a0[i+1] = 0;
|
||||||
fBrake_a1[i+1] = 0;
|
fBrake_a1[i+1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( OrderCurrentGet() & Shunt ) {
|
||||||
|
// for uniform behaviour and compatibility with older scenarios set default acceleration table values for shunting
|
||||||
|
fAccThreshold = (
|
||||||
|
mvOccupied->TrainType == dt_EZT ? -0.55 :
|
||||||
|
mvOccupied->TrainType == dt_DMU ? -0.45 :
|
||||||
|
-0.2 );
|
||||||
|
// HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors
|
||||||
|
if( ( mvOccupied->TrainType == dt_EZT )
|
||||||
|
&& ( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) ) {
|
||||||
|
fAccThreshold += 0.10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( OrderCurrentGet() & Obey_train ) {
|
||||||
// 4. Przeliczanie siły hamowania
|
// 4. Przeliczanie siły hamowania
|
||||||
double const velstep = ( mvOccupied->Vmax*0.5 ) / BrakeAccTableSize;
|
double const velstep = ( mvOccupied->Vmax*0.5 ) / BrakeAccTableSize;
|
||||||
d = pVehicles[0]; // pojazd na czele składu
|
d = pVehicles[0]; // pojazd na czele składu
|
||||||
@@ -1969,12 +1993,7 @@ void TController::AutoRewident()
|
|||||||
fBrakeReaction = 1.00 + fLength*0.005;
|
fBrakeReaction = 1.00 + fLength*0.005;
|
||||||
}
|
}
|
||||||
fAccThreshold = fNominalAccThreshold;
|
fAccThreshold = fNominalAccThreshold;
|
||||||
/*
|
|
||||||
if( IsHeavyCargoTrain ) {
|
|
||||||
// HACK: heavy cargo trains don't activate brakes early enough
|
|
||||||
fAccThreshold = std::max( -0.2, fAccThreshold );
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double TController::ESMVelocity(bool Main)
|
double TController::ESMVelocity(bool Main)
|
||||||
@@ -2852,7 +2871,11 @@ bool TController::IncSpeed()
|
|||||||
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 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 { mvControlling->EnginePowerSource.CollectorParameters.MaxV * ( IsHeavyCargoTrain ? 0.70 : 0.80 ) };
|
auto const useseriesmodevoltage {
|
||||||
|
interpolate(
|
||||||
|
mvControlling->EnginePowerSource.CollectorParameters.MinV,
|
||||||
|
mvControlling->EnginePowerSource.CollectorParameters.MaxV,
|
||||||
|
( IsHeavyCargoTrain ? 0.35 : 0.40 ) ) };
|
||||||
auto const useseriesmode = (
|
auto const useseriesmode = (
|
||||||
( mvControlling->Imax > mvControlling->ImaxLo )
|
( mvControlling->Imax > mvControlling->ImaxLo )
|
||||||
|| ( fVoltage < useseriesmodevoltage )
|
|| ( fVoltage < useseriesmodevoltage )
|
||||||
@@ -2883,10 +2906,12 @@ bool TController::IncSpeed()
|
|||||||
if( usefieldshunting ) {
|
if( usefieldshunting ) {
|
||||||
// to dać bocznik
|
// to dać bocznik
|
||||||
// engage the shuntfield only if there's sufficient power margin to draw from
|
// engage the shuntfield only if there's sufficient power margin to draw from
|
||||||
|
auto const sufficientpowermargin { fVoltage - useseriesmodevoltage > ( IsHeavyCargoTrain ? 100.0 : 75.0 ) };
|
||||||
|
|
||||||
OK = (
|
OK = (
|
||||||
fVoltage > useseriesmodevoltage + 0.0125 * mvControlling->EnginePowerSource.CollectorParameters.MaxV ?
|
sufficientpowermargin ?
|
||||||
mvControlling->IncScndCtrl( 1 ) :
|
mvControlling->IncScndCtrl( 1 ) :
|
||||||
false );
|
true );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// jeśli ustawiony bocznik to bocznik na zero po chamsku
|
// jeśli ustawiony bocznik to bocznik na zero po chamsku
|
||||||
@@ -2894,10 +2919,19 @@ bool TController::IncSpeed()
|
|||||||
mvControlling->DecScndCtrl( 2 );
|
mvControlling->DecScndCtrl( 2 );
|
||||||
}
|
}
|
||||||
// kręcimy nastawnik jazdy
|
// kręcimy nastawnik jazdy
|
||||||
|
// don't draw too much power;
|
||||||
|
// keep from dropping into series mode when entering/using parallel mode, and from shutting down in the series mode
|
||||||
|
auto const sufficientpowermargin {
|
||||||
|
fVoltage - (
|
||||||
|
mvControlling->RList[ std::min( mvControlling->MainCtrlPos + 1, mvControlling->MainCtrlPosNo ) ].Bn == 1 ?
|
||||||
|
mvControlling->EnginePowerSource.CollectorParameters.MinV :
|
||||||
|
useseriesmodevoltage )
|
||||||
|
> ( IsHeavyCargoTrain ? 80.0 : 60.0 ) };
|
||||||
|
|
||||||
OK = (
|
OK = (
|
||||||
mvControlling->DelayCtrlFlag ?
|
( sufficientpowermargin && ( false == mvControlling->DelayCtrlFlag ) ) ?
|
||||||
true :
|
mvControlling->IncMainCtrl( 1 ) :
|
||||||
mvControlling->IncMainCtrl( 1 ) );
|
true );
|
||||||
// czekaj na 1 pozycji, zanim się nie włączą liniowe
|
// czekaj na 1 pozycji, zanim się nie włączą liniowe
|
||||||
if( true == mvControlling->StLinFlag ) {
|
if( true == mvControlling->StLinFlag ) {
|
||||||
iDrivigFlags |= moveIncSpeed;
|
iDrivigFlags |= moveIncSpeed;
|
||||||
@@ -3903,12 +3937,13 @@ TController::UpdateSituation(double dt) {
|
|||||||
p = p->Next(); // pojazd podłączony z tyłu (patrząc od czoła)
|
p = p->Next(); // pojazd podłączony z tyłu (patrząc od czoła)
|
||||||
}
|
}
|
||||||
|
|
||||||
// crude way to deal with automatic door opening on W4 preventing further ride
|
// HACK: crude way to deal with automatic door opening on W4 preventing further ride
|
||||||
// for human-controlled vehicles with no door control and dynamic brake auto-activating with door open
|
// for human-controlled vehicles with no door control and dynamic brake auto-activating with door open
|
||||||
|
// TODO: check if this situation still happens and the hack is still needed
|
||||||
if( ( false == AIControllFlag )
|
if( ( false == AIControllFlag )
|
||||||
&& ( iDrivigFlags & moveDoorOpened )
|
&& ( iDrivigFlags & moveDoorOpened )
|
||||||
&& ( mvOccupied->DoorCloseCtrl != control_t::driver )
|
&& ( mvOccupied->DoorCloseCtrl != control_t::driver )
|
||||||
&& ( mvControlling->MainCtrlPos > 0 ) ) {
|
&& ( mvControlling->MainCtrlPos > ( mvControlling->EngineType != TEngineType::DieselEngine ? 0 : 1 ) ) ) { // for diesel 1st position is effectively 0
|
||||||
Doors( false );
|
Doors( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4006,7 +4041,15 @@ TController::UpdateSituation(double dt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( fVoltage < 0.75 * mvControlling->EnginePowerSource.CollectorParameters.MaxV ) {
|
|
||||||
|
// TODO: refactor this calculation into a subroutine
|
||||||
|
auto const useseriesmodevoltage {
|
||||||
|
interpolate(
|
||||||
|
mvControlling->EnginePowerSource.CollectorParameters.MinV,
|
||||||
|
mvControlling->EnginePowerSource.CollectorParameters.MaxV,
|
||||||
|
( IsHeavyCargoTrain ? 0.35 : 0.40 ) ) };
|
||||||
|
|
||||||
|
if( fVoltage <= useseriesmodevoltage ) {
|
||||||
// if the power station is heavily burdened try to reduce the load
|
// if the power station is heavily burdened try to reduce the load
|
||||||
switch( mvControlling->EngineType ) {
|
switch( mvControlling->EngineType ) {
|
||||||
|
|
||||||
@@ -5856,14 +5899,22 @@ basic_event * TController::CheckTrackEventBackward(double fDirection, TTrack *Tr
|
|||||||
{ // sprawdzanie eventu w torze, czy jest sygnałowym - skanowanie do tyłu
|
{ // sprawdzanie eventu w torze, czy jest sygnałowym - skanowanie do tyłu
|
||||||
// NOTE: this method returns only one event which meets the conditions, due to limitations in the caller
|
// NOTE: this method returns only one event which meets the conditions, due to limitations in the caller
|
||||||
// TBD, TODO: clean up the caller and return all suitable events, as in theory things will go awry if the track has more than one signal
|
// TBD, TODO: clean up the caller and return all suitable events, as in theory things will go awry if the track has more than one signal
|
||||||
|
auto const dir{ pVehicles[ 0 ]->VectorFront() * pVehicles[ 0 ]->DirectionGet() };
|
||||||
|
auto const pos{ pVehicles[ 0 ]->HeadPosition() };
|
||||||
auto const &eventsequence { ( fDirection > 0 ? Track->m_events2 : Track->m_events1 ) };
|
auto const &eventsequence { ( fDirection > 0 ? Track->m_events2 : Track->m_events1 ) };
|
||||||
for( auto const &event : eventsequence ) {
|
for( auto const &event : eventsequence ) {
|
||||||
if( ( event.second != nullptr )
|
if( ( event.second != nullptr )
|
||||||
&& ( event.second->m_passive )
|
&& ( event.second->m_passive )
|
||||||
&& ( typeid(*(event.second)) == typeid( getvalues_event ) ) ) {
|
&& ( typeid(*(event.second)) == typeid( getvalues_event ) ) ) {
|
||||||
|
// since we're checking for events behind us discard the sources in front of the scanning vehicle
|
||||||
|
auto const sl{ event.second->input_location() }; // położenie komórki pamięci
|
||||||
|
auto const sem{ sl - pos }; // wektor do komórki pamięci od końca składu
|
||||||
|
if( dir.x * sem.x + dir.z * sem.z < 0 ) {
|
||||||
|
// iloczyn skalarny jest ujemny, gdy sygnał stoi z tyłu
|
||||||
return event.second;
|
return event.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
4
Driver.h
4
Driver.h
@@ -141,7 +141,7 @@ class TSpeedPos
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
TSpeedPos(TTrack *track, double dist, int flag);
|
TSpeedPos(TTrack *track, double dist, int flag);
|
||||||
TSpeedPos(basic_event *event, double dist, TOrders order);
|
TSpeedPos(basic_event *event, double dist, double length, TOrders order);
|
||||||
TSpeedPos() = default;
|
TSpeedPos() = default;
|
||||||
void Clear();
|
void Clear();
|
||||||
bool Update();
|
bool Update();
|
||||||
@@ -150,7 +150,7 @@ class TSpeedPos
|
|||||||
void
|
void
|
||||||
UpdateDistance( double dist ) {
|
UpdateDistance( double dist ) {
|
||||||
fDist -= dist; }
|
fDist -= dist; }
|
||||||
bool Set(basic_event *e, double d, TOrders order = Wait_for_orders);
|
bool Set(basic_event *e, double d, double length, TOrders order = Wait_for_orders);
|
||||||
void Set(TTrack *t, double d, int f);
|
void Set(TTrack *t, double d, int f);
|
||||||
std::string TableText() const;
|
std::string TableText() const;
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
|
|||||||
@@ -2780,7 +2780,7 @@ TDynamicObject::update_load_visibility() {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
auto loadpercentage { (
|
auto loadpercentage { (
|
||||||
MoverParameters->MaxLoad == 0.0 ?
|
MoverParameters->MaxLoad == 0.f ?
|
||||||
0.0 :
|
0.0 :
|
||||||
100.0 * MoverParameters->LoadAmount / MoverParameters->MaxLoad ) };
|
100.0 * MoverParameters->LoadAmount / MoverParameters->MaxLoad ) };
|
||||||
auto const sectionloadpercentage { (
|
auto const sectionloadpercentage { (
|
||||||
@@ -2814,7 +2814,7 @@ TDynamicObject::update_load_offset() {
|
|||||||
if( MoverParameters->LoadType.offset_min == 0.f ) { return; }
|
if( MoverParameters->LoadType.offset_min == 0.f ) { return; }
|
||||||
|
|
||||||
auto const loadpercentage { (
|
auto const loadpercentage { (
|
||||||
MoverParameters->MaxLoad == 0.0 ?
|
MoverParameters->MaxLoad == 0.f ?
|
||||||
0.0 :
|
0.0 :
|
||||||
100.0 * MoverParameters->LoadAmount / MoverParameters->MaxLoad ) };
|
100.0 * MoverParameters->LoadAmount / MoverParameters->MaxLoad ) };
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ basic_event::event_conditions::test() const {
|
|||||||
match_value_2,
|
match_value_2,
|
||||||
flags );
|
flags );
|
||||||
|
|
||||||
std::string comparisonlog = "Test: MemCompare - ";
|
std::string comparisonlog = "Test: MemCompare - " + cell->name() + " - ";
|
||||||
|
|
||||||
comparisonlog +=
|
comparisonlog +=
|
||||||
"[" + cell->Text() + "]"
|
"[" + cell->Text() + "]"
|
||||||
|
|||||||
@@ -374,6 +374,14 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
Parser.getTokens();
|
Parser.getTokens();
|
||||||
Parser >> ResourceMove;
|
Parser >> ResourceMove;
|
||||||
}
|
}
|
||||||
|
else if( token == "gfx.reflections.framerate" ) {
|
||||||
|
|
||||||
|
auto const updatespersecond { std::abs( Parser.getToken<double>() ) };
|
||||||
|
ReflectionUpdatesPerSecond = (
|
||||||
|
updatespersecond > 0 ?
|
||||||
|
1000 / std::min( 30.0, updatespersecond ) :
|
||||||
|
0 );
|
||||||
|
}
|
||||||
else if (token == "timespeed")
|
else if (token == "timespeed")
|
||||||
{
|
{
|
||||||
// przyspieszenie czasu, zmienna do testów
|
// przyspieszenie czasu, zmienna do testów
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ struct global_settings {
|
|||||||
float depth{ 250.f };
|
float depth{ 250.f };
|
||||||
float distance{ 500.f }; // no longer used
|
float distance{ 500.f }; // no longer used
|
||||||
} shadowtune;
|
} shadowtune;
|
||||||
|
int ReflectionUpdatesPerSecond{ static_cast<int>( 1000 / ( 1.0 / 300.0 ) ) };
|
||||||
float AnisotropicFiltering{ 8.f }; // requested level of anisotropic filtering. TODO: move it to renderer object
|
float AnisotropicFiltering{ 8.f }; // requested level of anisotropic filtering. TODO: move it to renderer object
|
||||||
float FieldOfView{ 45.f }; // vertical field of view for the camera. TODO: move it to the renderer
|
float FieldOfView{ 45.f }; // vertical field of view for the camera. TODO: move it to the renderer
|
||||||
GLint iMaxTextureSize{ 4096 }; // maksymalny rozmiar tekstury
|
GLint iMaxTextureSize{ 4096 }; // maksymalny rozmiar tekstury
|
||||||
|
|||||||
@@ -1003,13 +1003,6 @@ public:
|
|||||||
TRotation Rot { 0.0, 0.0, 0.0 };
|
TRotation Rot { 0.0, 0.0, 0.0 };
|
||||||
std::string Name; /*nazwa wlasna*/
|
std::string Name; /*nazwa wlasna*/
|
||||||
TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami
|
TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami
|
||||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
|
||||||
double HVCouplers[ 2 ][ 2 ]; //przewod WN
|
|
||||||
enum hvcoupler {
|
|
||||||
current = 0,
|
|
||||||
voltage
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/
|
bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/
|
||||||
int SoundFlag = 0; /*!o patrz stale sound_ */
|
int SoundFlag = 0; /*!o patrz stale sound_ */
|
||||||
double DistCounter = 0.0; /*! licznik kilometrow */
|
double DistCounter = 0.0; /*! licznik kilometrow */
|
||||||
|
|||||||
@@ -316,12 +316,6 @@ ActiveCab( Cab )
|
|||||||
Couplers[b].DmaxC = 0.1;
|
Couplers[b].DmaxC = 0.1;
|
||||||
Couplers[b].FmaxC = 1000.0;
|
Couplers[b].FmaxC = 1000.0;
|
||||||
}
|
}
|
||||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
|
||||||
for( int side = 0; side < 2; ++side ) {
|
|
||||||
HVCouplers[ side ][ hvcoupler::current ] = 0.0;
|
|
||||||
HVCouplers[ side ][ hvcoupler::voltage ] = 0.0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
for( int b = 0; b < 3; ++b ) {
|
for( int b = 0; b < 3; ++b ) {
|
||||||
BrakeCylMult[ b ] = 0.0;
|
BrakeCylMult[ b ] = 0.0;
|
||||||
}
|
}
|
||||||
@@ -816,13 +810,23 @@ void TMoverParameters::UpdateBatteryVoltage(double dt)
|
|||||||
&& ( EngineType != TEngineType::WheelsDriven )
|
&& ( EngineType != TEngineType::WheelsDriven )
|
||||||
&& ( NominalBatteryVoltage > 0 ) ) {
|
&& ( NominalBatteryVoltage > 0 ) ) {
|
||||||
|
|
||||||
|
// HACK: allow to draw power also from adjacent converter, applicable for EMUs
|
||||||
|
// TODO: expand power cables system to include low voltage power transfers
|
||||||
|
// HACK: emulate low voltage generator powered directly by the diesel engine
|
||||||
|
auto const converteractive{ (
|
||||||
|
( ConverterFlag )
|
||||||
|
|| ( ( ( Couplers[ side::front ].CouplingFlag & coupling::permanent ) != 0 ) && Couplers[ side::front ].Connected->ConverterFlag )
|
||||||
|
|| ( ( ( Couplers[ side::rear ].CouplingFlag & coupling::permanent ) != 0 ) && Couplers[ side::rear ].Connected->ConverterFlag ) )
|
||||||
|
|| ( ( EngineType == TEngineType::DieselElectric ) && ( true == Mains ) )
|
||||||
|
|| ( ( EngineType == TEngineType::DieselEngine ) && ( true == Mains ) ) };
|
||||||
|
|
||||||
if ((NominalBatteryVoltage / BatteryVoltage < 1.22) && Battery)
|
if ((NominalBatteryVoltage / BatteryVoltage < 1.22) && Battery)
|
||||||
{ // 110V
|
{ // 110V
|
||||||
if (!ConverterFlag)
|
if (!converteractive)
|
||||||
sn1 = (dt * 2.0); // szybki spadek do ok 90V
|
sn1 = (dt * 2.0); // szybki spadek do ok 90V
|
||||||
else
|
else
|
||||||
sn1 = 0;
|
sn1 = 0;
|
||||||
if (ConverterFlag)
|
if (converteractive)
|
||||||
sn2 = -(dt * 2.0); // szybki wzrost do 110V
|
sn2 = -(dt * 2.0); // szybki wzrost do 110V
|
||||||
else
|
else
|
||||||
sn2 = 0;
|
sn2 = 0;
|
||||||
@@ -846,7 +850,7 @@ void TMoverParameters::UpdateBatteryVoltage(double dt)
|
|||||||
sn1 = (dt * 0.0046);
|
sn1 = (dt * 0.0046);
|
||||||
else
|
else
|
||||||
sn1 = 0;
|
sn1 = 0;
|
||||||
if (ConverterFlag)
|
if (converteractive)
|
||||||
sn2 = -(dt * 50); // szybki wzrost do 110V
|
sn2 = -(dt * 50); // szybki wzrost do 110V
|
||||||
else
|
else
|
||||||
sn2 = 0;
|
sn2 = 0;
|
||||||
@@ -1120,33 +1124,18 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
|||||||
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|
||||||
|| ( ( Heating )
|
|| ( ( Heating )
|
||||||
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
|
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
|
||||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
|
||||||
HVCouplers[ oppositeside ][ hvcoupler::voltage ] =
|
|
||||||
std::max(
|
|
||||||
std::abs( hvc ),
|
|
||||||
Couplers[ side ].Connected->HVCouplers[ Couplers[ side ].ConnectedNr ][ hvcoupler::voltage ] - HVCouplers[ side ][ hvcoupler::current ] * 0.02 );
|
|
||||||
#else
|
|
||||||
auto const &connectedcoupler = Couplers[ side ].Connected->Couplers[ Couplers[ side ].ConnectedNr ];
|
auto const &connectedcoupler = Couplers[ side ].Connected->Couplers[ Couplers[ side ].ConnectedNr ];
|
||||||
Couplers[ oppositeside ].power_high.voltage =
|
Couplers[ oppositeside ].power_high.voltage =
|
||||||
std::max(
|
std::max(
|
||||||
std::abs( hvc ),
|
std::abs( hvc ),
|
||||||
connectedcoupler.power_high.voltage - Couplers[ side ].power_high.current * 0.02 );
|
connectedcoupler.power_high.voltage - Couplers[ side ].power_high.current * 0.02 );
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
|
||||||
HVCouplers[ oppositeside ][ hvcoupler::voltage ] = std::abs( hvc ) - HVCouplers[ side ][ hvcoupler::current ] * 0.02;
|
|
||||||
#else
|
|
||||||
Couplers[ oppositeside ].power_high.voltage = std::abs( hvc ) - Couplers[ side ].power_high.current * 0.02;
|
Couplers[ oppositeside ].power_high.voltage = std::abs( hvc ) - Couplers[ side ].power_high.current * 0.02;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
|
||||||
hvc = HVCouplers[ side::front ][ hvcoupler::voltage ] + HVCouplers[ side::rear ][ hvcoupler::voltage ];
|
|
||||||
#else
|
|
||||||
hvc = Couplers[ side::front ].power_high.voltage + Couplers[ side::rear ].power_high.voltage;
|
hvc = Couplers[ side::front ].power_high.voltage + Couplers[ side::rear ].power_high.voltage;
|
||||||
#endif
|
|
||||||
|
|
||||||
if( std::abs( PantFrontVolt ) + std::abs( PantRearVolt ) < 1.0 ) {
|
if( std::abs( PantFrontVolt ) + std::abs( PantRearVolt ) < 1.0 ) {
|
||||||
// bez napiecia...
|
// bez napiecia...
|
||||||
@@ -1160,29 +1149,17 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
|||||||
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|
||||||
|| ( ( Heating )
|
|| ( ( Heating )
|
||||||
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
|
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
|
||||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
auto const &connectedcoupler =
|
||||||
auto const oppositeside = ( Couplers[side].ConnectedNr == side::front ? side::rear : side::front );
|
|
||||||
HVCouplers[ side ][ hvcoupler::current ] =
|
|
||||||
Couplers[side].Connected->HVCouplers[oppositeside][hvcoupler::current] +
|
|
||||||
Itot * HVCouplers[side][hvcoupler::voltage] / hvc; // obciążenie rozkladane stosownie do napiec
|
|
||||||
#else
|
|
||||||
auto const &connectedsothercoupler =
|
|
||||||
Couplers[ side ].Connected->Couplers[
|
Couplers[ side ].Connected->Couplers[
|
||||||
( Couplers[ side ].ConnectedNr == side::front ?
|
( Couplers[ side ].ConnectedNr == side::front ?
|
||||||
side::rear :
|
side::rear :
|
||||||
side::front ) ];
|
side::front ) ];
|
||||||
Couplers[ side ].power_high.current =
|
Couplers[ side ].power_high.current =
|
||||||
connectedsothercoupler.power_high.current
|
connectedcoupler.power_high.current
|
||||||
+ Itot * Couplers[ side ].power_high.voltage / hvc; // obciążenie rozkladane stosownie do napiec
|
+ Itot * Couplers[ side ].power_high.voltage / hvc; // obciążenie rozkladane stosownie do napiec
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
|
||||||
// pierwszy pojazd
|
|
||||||
HVCouplers[side][hvcoupler::current] = Itot * HVCouplers[side][hvcoupler::voltage] / hvc;
|
|
||||||
#else
|
|
||||||
Couplers[ side ].power_high.current = Itot * Couplers[ side ].power_high.voltage / hvc;
|
Couplers[ side ].power_high.current = Itot * Couplers[ side ].power_high.voltage / hvc;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1196,19 +1173,13 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
|||||||
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|
||||||
|| ( ( Heating )
|
|| ( ( Heating )
|
||||||
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
|
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
|
||||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
auto const &connectedcoupler =
|
||||||
auto const oppositeside = ( Couplers[ side ].ConnectedNr == side::front ? side::rear : side::front );
|
|
||||||
TotalCurrent += Couplers[ side ].Connected->HVCouplers[ oppositeside ][ hvcoupler::current ];
|
|
||||||
HVCouplers[ side ][ hvcoupler::current ] = 0.0;
|
|
||||||
#else
|
|
||||||
auto const &connectedsothercoupler =
|
|
||||||
Couplers[ side ].Connected->Couplers[
|
Couplers[ side ].Connected->Couplers[
|
||||||
( Couplers[ side ].ConnectedNr == side::front ?
|
( Couplers[ side ].ConnectedNr == side::front ?
|
||||||
side::rear :
|
side::rear :
|
||||||
side::front ) ];
|
side::front ) ];
|
||||||
TotalCurrent += connectedsothercoupler.power_high.current;
|
TotalCurrent += connectedcoupler.power_high.current;
|
||||||
Couplers[ side ].power_high.current = 0.0;
|
Couplers[ side ].power_high.current = 0.0;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1561,11 +1532,6 @@ void TMoverParameters::WaterPumpCheck( double const Timestep ) {
|
|||||||
// water heater status check
|
// water heater status check
|
||||||
void TMoverParameters::WaterHeaterCheck( double const Timestep ) {
|
void TMoverParameters::WaterHeaterCheck( double const Timestep ) {
|
||||||
|
|
||||||
WaterHeater.is_damaged = (
|
|
||||||
( true == WaterHeater.is_damaged )
|
|
||||||
|| ( ( true == WaterHeater.is_active )
|
|
||||||
&& ( false == WaterPump.is_active ) ) );
|
|
||||||
|
|
||||||
WaterHeater.is_active = (
|
WaterHeater.is_active = (
|
||||||
( false == WaterHeater.is_damaged )
|
( false == WaterHeater.is_damaged )
|
||||||
&& ( true == Battery )
|
&& ( true == Battery )
|
||||||
@@ -1573,6 +1539,11 @@ void TMoverParameters::WaterHeaterCheck( double const Timestep ) {
|
|||||||
&& ( true == WaterHeater.breaker )
|
&& ( true == WaterHeater.breaker )
|
||||||
&& ( ( WaterHeater.is_active ) || ( WaterHeater.config.temp_min < 0 ) || ( dizel_heat.temperatura1 < WaterHeater.config.temp_min ) ) );
|
&& ( ( WaterHeater.is_active ) || ( WaterHeater.config.temp_min < 0 ) || ( dizel_heat.temperatura1 < WaterHeater.config.temp_min ) ) );
|
||||||
|
|
||||||
|
WaterHeater.is_damaged = (
|
||||||
|
( true == WaterHeater.is_damaged )
|
||||||
|
|| ( ( true == WaterHeater.is_active )
|
||||||
|
&& ( false == WaterPump.is_active ) ) );
|
||||||
|
|
||||||
if( ( WaterHeater.config.temp_max > 0 )
|
if( ( WaterHeater.config.temp_max > 0 )
|
||||||
&& ( dizel_heat.temperatura1 > WaterHeater.config.temp_max ) ) {
|
&& ( dizel_heat.temperatura1 > WaterHeater.config.temp_max ) ) {
|
||||||
WaterHeater.is_active = false;
|
WaterHeater.is_active = false;
|
||||||
@@ -4017,11 +3988,9 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer)
|
|||||||
Voltage =
|
Voltage =
|
||||||
std::max(
|
std::max(
|
||||||
RunningTraction.TractionVoltage,
|
RunningTraction.TractionVoltage,
|
||||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
std::max(
|
||||||
std::max( HVCouplers[side::front][hvcoupler::voltage], HVCouplers[side::rear][hvcoupler::voltage] ) );
|
Couplers[ side::front ].power_high.voltage,
|
||||||
#else
|
Couplers[ side::rear ].power_high.voltage ) );
|
||||||
std::max( Couplers[ side::front ].power_high.voltage, Couplers[ side::rear ].power_high.voltage ) );
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Voltage = 0;
|
Voltage = 0;
|
||||||
@@ -6708,7 +6677,7 @@ TMoverParameters::AssignLoad( std::string const &Name, float const Amount ) {
|
|||||||
for( auto const &loadattributes : LoadAttributes ) {
|
for( auto const &loadattributes : LoadAttributes ) {
|
||||||
if( Name == loadattributes.name ) {
|
if( Name == loadattributes.name ) {
|
||||||
LoadType = loadattributes;
|
LoadType = loadattributes;
|
||||||
LoadAmount = Amount;
|
LoadAmount = clamp( Amount, 0.f, MaxLoad ) ;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6746,7 +6715,7 @@ bool TMoverParameters::LoadingDone(double const LSpeed, std::string const &Loadn
|
|||||||
if( ( LoadAmount <= 0 ) || ( CommandIn.Value1 <= 0 ) ) {
|
if( ( LoadAmount <= 0 ) || ( CommandIn.Value1 <= 0 ) ) {
|
||||||
// pusto lub rozładowano żądaną ilość
|
// pusto lub rozładowano żądaną ilość
|
||||||
LoadStatus = 4; // skończony rozładunek
|
LoadStatus = 4; // skończony rozładunek
|
||||||
LoadAmount = std::max( 0.f, LoadAmount ); //ładunek nie może być ujemny
|
LoadAmount = clamp( LoadAmount, 0.f, MaxLoad); //ładunek nie może być ujemny
|
||||||
}
|
}
|
||||||
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
|
||||||
@@ -7033,16 +7002,6 @@ std::string TMoverParameters::EngineDescription(int what) const
|
|||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
double TMoverParameters::GetTrainsetVoltage(void)
|
double TMoverParameters::GetTrainsetVoltage(void)
|
||||||
{//ABu: funkcja zwracajaca napiecie dla calego skladu, przydatna dla EZT
|
{//ABu: funkcja zwracajaca napiecie dla calego skladu, przydatna dla EZT
|
||||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
|
||||||
return std::max(
|
|
||||||
HVCouplers[ side::front ][ hvcoupler::voltage ],
|
|
||||||
HVCouplers[ side::rear ][ hvcoupler::voltage ] );
|
|
||||||
#else
|
|
||||||
/*
|
|
||||||
return std::max(
|
|
||||||
Couplers[ side::front ].power_high.voltage,
|
|
||||||
Couplers[ side::rear ].power_high.voltage );
|
|
||||||
*/
|
|
||||||
return std::max(
|
return std::max(
|
||||||
( ( ( Couplers[side::front].Connected )
|
( ( ( Couplers[side::front].Connected )
|
||||||
&& ( ( Couplers[ side::front ].CouplingFlag & ctrain_power )
|
&& ( ( Couplers[ side::front ].CouplingFlag & ctrain_power )
|
||||||
@@ -7056,7 +7015,6 @@ double TMoverParameters::GetTrainsetVoltage(void)
|
|||||||
&& ( Couplers[ side::rear ].CouplingFlag & ctrain_heating ) ) ) ) ?
|
&& ( Couplers[ side::rear ].CouplingFlag & ctrain_heating ) ) ) ) ?
|
||||||
Couplers[ side::rear ].Connected->Couplers[ Couplers[ side::rear ].ConnectedNr ].power_high.voltage :
|
Couplers[ side::rear ].Connected->Couplers[ Couplers[ side::rear ].ConnectedNr ].power_high.voltage :
|
||||||
0.0 ) );
|
0.0 ) );
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
|
|||||||
69
Train.cpp
69
Train.cpp
@@ -452,9 +452,9 @@ PyObject *TTrain::GetTrainState() {
|
|||||||
// basic systems state data
|
// basic systems state data
|
||||||
PyDict_SetItemString( dict, "battery", PyGetBool( mvControlled->Battery ) );
|
PyDict_SetItemString( dict, "battery", PyGetBool( mvControlled->Battery ) );
|
||||||
PyDict_SetItemString( dict, "linebreaker", PyGetBool( mvControlled->Mains ) );
|
PyDict_SetItemString( dict, "linebreaker", PyGetBool( mvControlled->Mains ) );
|
||||||
PyDict_SetItemString( dict, "converter", PyGetBool( mover->ConverterFlag ) );
|
PyDict_SetItemString( dict, "converter", PyGetBool( mvControlled->ConverterFlag ) );
|
||||||
PyDict_SetItemString( dict, "converter_overload", PyGetBool( mover->ConvOvldFlag ) );
|
PyDict_SetItemString( dict, "converter_overload", PyGetBool( mvControlled->ConvOvldFlag ) );
|
||||||
PyDict_SetItemString( dict, "compress", PyGetBool( mover->CompressorFlag ) );
|
PyDict_SetItemString( dict, "compress", PyGetBool( mvControlled->CompressorFlag ) );
|
||||||
// reverser
|
// reverser
|
||||||
PyDict_SetItemString( dict, "direction", PyGetInt( mover->ActiveDir ) );
|
PyDict_SetItemString( dict, "direction", PyGetInt( mover->ActiveDir ) );
|
||||||
// throttle
|
// throttle
|
||||||
@@ -467,34 +467,35 @@ PyObject *TTrain::GetTrainState() {
|
|||||||
bool const bEP = ( mvControlled->LocHandle->GetCP() > 0.2 ) || ( fEIMParams[ 0 ][ 2 ] > 0.01 );
|
bool const bEP = ( mvControlled->LocHandle->GetCP() > 0.2 ) || ( fEIMParams[ 0 ][ 2 ] > 0.01 );
|
||||||
PyDict_SetItemString( dict, "dir_brake", PyGetBool( bEP ) );
|
PyDict_SetItemString( dict, "dir_brake", PyGetBool( bEP ) );
|
||||||
bool bPN;
|
bool bPN;
|
||||||
if( ( typeid( *mvControlled->Hamulec ) == typeid( TLSt ) )
|
if( ( typeid( *mvOccupied->Hamulec ) == typeid( TLSt ) )
|
||||||
|| ( typeid( *mvControlled->Hamulec ) == typeid( TEStED ) ) ) {
|
|| ( typeid( *mvOccupied->Hamulec ) == typeid( TEStED ) ) ) {
|
||||||
|
|
||||||
TBrake* temp_ham = mvControlled->Hamulec.get();
|
TBrake* temp_ham = mvOccupied->Hamulec.get();
|
||||||
bPN = ( static_cast<TLSt*>( temp_ham )->GetEDBCP() > 0.2 );
|
bPN = ( static_cast<TLSt*>( temp_ham )->GetEDBCP() > 0.2 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bPN = false;
|
bPN = false;
|
||||||
PyDict_SetItemString( dict, "indir_brake", PyGetBool( bPN ) );
|
PyDict_SetItemString( dict, "indir_brake", PyGetBool( bPN ) );
|
||||||
PyDict_SetItemString( dict, "brake_delay_flag", PyGetInt( mvControlled->BrakeDelayFlag ));
|
PyDict_SetItemString( dict, "brake_delay_flag", PyGetInt( mvOccupied->BrakeDelayFlag ));
|
||||||
PyDict_SetItemString( dict, "brake_op_mode_flag", PyGetInt( mvControlled->BrakeOpModeFlag ));
|
PyDict_SetItemString( dict, "brake_op_mode_flag", PyGetInt( mvOccupied->BrakeOpModeFlag ));
|
||||||
// other controls
|
// other controls
|
||||||
PyDict_SetItemString( dict, "ca", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) ) );
|
PyDict_SetItemString( dict, "ca", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) ) );
|
||||||
PyDict_SetItemString( dict, "shp", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_active ) ) );
|
PyDict_SetItemString( dict, "shp", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_active ) ) );
|
||||||
PyDict_SetItemString( dict, "pantpress", PyGetFloat( mvControlled->PantPress ) );
|
PyDict_SetItemString( dict, "pantpress", PyGetFloat( mvControlled->PantPress ) );
|
||||||
PyDict_SetItemString( dict, "universal3", PyGetBool( InstrumentLightActive ) );
|
PyDict_SetItemString( dict, "universal3", PyGetBool( InstrumentLightActive ) );
|
||||||
PyDict_SetItemString( dict, "radio_channel", PyGetInt( iRadioChannel ) );
|
PyDict_SetItemString( dict, "radio_channel", PyGetInt( iRadioChannel ) );
|
||||||
|
PyDict_SetItemString( dict, "door_lock", PyGetInt( mvOccupied->DoorLockEnabled ) );
|
||||||
// movement data
|
// movement data
|
||||||
PyDict_SetItemString( dict, "velocity", PyGetFloat( mover->Vel ) );
|
PyDict_SetItemString( dict, "velocity", PyGetFloat( mover->Vel ) );
|
||||||
PyDict_SetItemString( dict, "tractionforce", PyGetFloat( mover->Ft ) );
|
PyDict_SetItemString( dict, "tractionforce", PyGetFloat( mover->Ft ) );
|
||||||
PyDict_SetItemString( dict, "slipping_wheels", PyGetBool( mover->SlippingWheels ) );
|
PyDict_SetItemString( dict, "slipping_wheels", PyGetBool( mover->SlippingWheels ) );
|
||||||
PyDict_SetItemString( dict, "sanding", PyGetBool( mover->SandDose ) );
|
PyDict_SetItemString( dict, "sanding", PyGetBool( mover->SandDose ) );
|
||||||
// electric current data
|
// electric current data
|
||||||
PyDict_SetItemString( dict, "traction_voltage", PyGetFloat( mover->RunningTraction.TractionVoltage ) );
|
PyDict_SetItemString( dict, "traction_voltage", PyGetFloat( mvControlled->RunningTraction.TractionVoltage ) );
|
||||||
PyDict_SetItemString( dict, "voltage", PyGetFloat( mover->Voltage ) );
|
PyDict_SetItemString( dict, "voltage", PyGetFloat( mvControlled->Voltage ) );
|
||||||
PyDict_SetItemString( dict, "im", PyGetFloat( mover->Im ) );
|
PyDict_SetItemString( dict, "im", PyGetFloat( mvControlled->Im ) );
|
||||||
PyDict_SetItemString( dict, "fuse", PyGetBool( mover->FuseFlag ) );
|
PyDict_SetItemString( dict, "fuse", PyGetBool( mvControlled->FuseFlag ) );
|
||||||
PyDict_SetItemString( dict, "epfuse", PyGetBool( mover->EpFuse ) );
|
PyDict_SetItemString( dict, "epfuse", PyGetBool( mvOccupied->EpFuse ) );
|
||||||
// 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" };
|
||||||
@@ -554,7 +555,7 @@ PyObject *TTrain::GetTrainState() {
|
|||||||
PyDict_SetItemString( dict, "train_enginetype", PyGetString( timetable->LocSeries.c_str() ) );
|
PyDict_SetItemString( dict, "train_enginetype", PyGetString( timetable->LocSeries.c_str() ) );
|
||||||
PyDict_SetItemString( dict, "train_engineload", PyGetFloat( timetable->LocLoad ) );
|
PyDict_SetItemString( dict, "train_engineload", PyGetFloat( timetable->LocLoad ) );
|
||||||
|
|
||||||
PyDict_SetItemString( dict, "train_stationindex", PyGetInt( driver->StationIndex() ) );
|
PyDict_SetItemString( dict, "train_stationindex", PyGetInt( driver->iStationStart ) );
|
||||||
auto const stationcount { driver->StationCount() };
|
auto const stationcount { driver->StationCount() };
|
||||||
PyDict_SetItemString( dict, "train_stationcount", PyGetInt( stationcount ) );
|
PyDict_SetItemString( dict, "train_stationcount", PyGetInt( stationcount ) );
|
||||||
if( stationcount > 0 ) {
|
if( stationcount > 0 ) {
|
||||||
@@ -579,6 +580,7 @@ PyObject *TTrain::GetTrainState() {
|
|||||||
PyDict_SetItemString( dict, "minutes", PyGetInt( simulation::Time.data().wMinute ) );
|
PyDict_SetItemString( dict, "minutes", PyGetInt( simulation::Time.data().wMinute ) );
|
||||||
PyDict_SetItemString( dict, "seconds", PyGetInt( simulation::Time.second() ) );
|
PyDict_SetItemString( dict, "seconds", PyGetInt( simulation::Time.second() ) );
|
||||||
PyDict_SetItemString( dict, "air_temperature", PyGetInt( Global.AirTemperature ) );
|
PyDict_SetItemString( dict, "air_temperature", PyGetInt( Global.AirTemperature ) );
|
||||||
|
PyDict_SetItemString( dict, "light_level", PyGetFloat( Global.fLuminance - std::max( 0.f, Global.Overcast - 1.f ) ) );
|
||||||
|
|
||||||
Application.release_python_lock();
|
Application.release_python_lock();
|
||||||
return dict;
|
return dict;
|
||||||
@@ -4084,14 +4086,14 @@ void TTrain::OnCommand_generictoggle( TTrain *Train, command_data const &Command
|
|||||||
|
|
||||||
auto const itemindex = static_cast<int>( Command.command ) - static_cast<int>( user_command::generictoggle0 );
|
auto const itemindex = static_cast<int>( Command.command ) - static_cast<int>( user_command::generictoggle0 );
|
||||||
auto &item = Train->ggUniversals[ itemindex ];
|
auto &item = Train->ggUniversals[ itemindex ];
|
||||||
|
/*
|
||||||
if( item.SubModel == nullptr ) {
|
if( item.SubModel == nullptr ) {
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
WriteLog( "Train generic item " + std::to_string( itemindex ) + " is missing, or wasn't defined" );
|
WriteLog( "Train generic item " + std::to_string( itemindex ) + " is missing, or wasn't defined" );
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||||
if( item.GetDesiredValue() < 0.5 ) {
|
if( item.GetDesiredValue() < 0.5 ) {
|
||||||
@@ -4995,8 +4997,10 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
iUnits[i] = iUnitNo;
|
iUnits[i] = iUnitNo;
|
||||||
cCode[i] = p->MoverParameters->TypeName[p->MoverParameters->TypeName.length() - 1];
|
cCode[i] = p->MoverParameters->TypeName[p->MoverParameters->TypeName.length() - 1];
|
||||||
asCarName[i] = p->name();
|
asCarName[i] = p->name();
|
||||||
bPants[iUnitNo - 1][0] = (bPants[iUnitNo - 1][0] || p->MoverParameters->PantFrontUp);
|
if( p->MoverParameters->EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) {
|
||||||
bPants[iUnitNo - 1][1] = (bPants[iUnitNo - 1][1] || p->MoverParameters->PantRearUp);
|
bPants[iUnitNo - 1][side::front] = ( bPants[iUnitNo - 1][side::front] || p->MoverParameters->PantFrontUp );
|
||||||
|
bPants[iUnitNo - 1][side::rear] = ( bPants[iUnitNo - 1][side::rear] || p->MoverParameters->PantRearUp );
|
||||||
|
}
|
||||||
bComp[iUnitNo - 1][0] = (bComp[iUnitNo - 1][0] || p->MoverParameters->CompressorAllow || (p->MoverParameters->CompressorStart == start_t::automatic));
|
bComp[iUnitNo - 1][0] = (bComp[iUnitNo - 1][0] || p->MoverParameters->CompressorAllow || (p->MoverParameters->CompressorStart == start_t::automatic));
|
||||||
bSlip[i] = p->MoverParameters->SlippingWheels;
|
bSlip[i] = p->MoverParameters->SlippingWheels;
|
||||||
if (p->MoverParameters->CompressorSpeed > 0.00001)
|
if (p->MoverParameters->CompressorSpeed > 0.00001)
|
||||||
@@ -5459,6 +5463,10 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
// others
|
// others
|
||||||
btLampkaMalfunction.Turn( mvControlled->dizel_heat.PA );
|
btLampkaMalfunction.Turn( mvControlled->dizel_heat.PA );
|
||||||
btLampkaMotorBlowers.Turn( ( mvControlled->MotorBlowers[ side::front ].is_active ) && ( mvControlled->MotorBlowers[ side::rear ].is_active ) );
|
btLampkaMotorBlowers.Turn( ( mvControlled->MotorBlowers[ side::front ].is_active ) && ( mvControlled->MotorBlowers[ side::rear ].is_active ) );
|
||||||
|
// universal devices state indicators
|
||||||
|
for( auto idx = 0; idx < btUniversals.size(); ++idx ) {
|
||||||
|
btUniversals[ idx ].Turn( ggUniversals[ idx ].GetValue() > 0.5 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// wylaczone
|
// wylaczone
|
||||||
@@ -5514,6 +5522,10 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
// others
|
// others
|
||||||
btLampkaMalfunction.Turn( false );
|
btLampkaMalfunction.Turn( false );
|
||||||
btLampkaMotorBlowers.Turn( false );
|
btLampkaMotorBlowers.Turn( false );
|
||||||
|
// universal devices state indicators
|
||||||
|
for( auto &universal : btUniversals ) {
|
||||||
|
universal.Turn( false );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // yB - wskazniki drugiego czlonu
|
{ // yB - wskazniki drugiego czlonu
|
||||||
@@ -6173,7 +6185,9 @@ void TTrain::update_sounds_runningnoise( sound_source &Sound ) {
|
|||||||
// volume calculation
|
// volume calculation
|
||||||
auto volume =
|
auto volume =
|
||||||
Sound.m_amplitudeoffset
|
Sound.m_amplitudeoffset
|
||||||
+ Sound.m_amplitudefactor * mvOccupied->Vel;
|
+ Sound.m_amplitudefactor * interpolate(
|
||||||
|
mvOccupied->Vel / ( 1 + mvOccupied->Vmax ), 1.0,
|
||||||
|
0.5 ); // scale base volume between 0.5-1.0
|
||||||
if( std::abs( mvOccupied->nrot ) > 0.01 ) {
|
if( std::abs( mvOccupied->nrot ) > 0.01 ) {
|
||||||
// hamulce wzmagaja halas
|
// hamulce wzmagaja halas
|
||||||
auto const brakeforceratio { (
|
auto const brakeforceratio { (
|
||||||
@@ -6197,7 +6211,7 @@ void TTrain::update_sounds_runningnoise( sound_source &Sound ) {
|
|||||||
interpolate(
|
interpolate(
|
||||||
0.0, 1.0,
|
0.0, 1.0,
|
||||||
clamp(
|
clamp(
|
||||||
mvOccupied->Vel / 40.0,
|
mvOccupied->Vel / 25.0,
|
||||||
0.0, 1.0 ) );
|
0.0, 1.0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7072,6 +7086,9 @@ void TTrain::clear_cab_controls()
|
|||||||
btLampkaHamulecReczny.Clear();
|
btLampkaHamulecReczny.Clear();
|
||||||
btLampkaBlokadaDrzwi.Clear();
|
btLampkaBlokadaDrzwi.Clear();
|
||||||
btLampkaDoorLockOff.Clear();
|
btLampkaDoorLockOff.Clear();
|
||||||
|
for( auto &universal : btUniversals ) {
|
||||||
|
universal.Clear();
|
||||||
|
}
|
||||||
btInstrumentLight.Clear();
|
btInstrumentLight.Clear();
|
||||||
btDashboardLight.Clear();
|
btDashboardLight.Clear();
|
||||||
btTimetableLight.Clear();
|
btTimetableLight.Clear();
|
||||||
@@ -7504,7 +7521,17 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
|||||||
{ "i-rearrightend:", btLampkaRearRightEndLight },
|
{ "i-rearrightend:", btLampkaRearRightEndLight },
|
||||||
{ "i-dashboardlight:", btDashboardLight },
|
{ "i-dashboardlight:", btDashboardLight },
|
||||||
{ "i-timetablelight:", btTimetableLight },
|
{ "i-timetablelight:", btTimetableLight },
|
||||||
{ "i-cablight:", btCabLight }
|
{ "i-cablight:", btCabLight },
|
||||||
|
{ "i-universal0:", btUniversals[ 0 ] },
|
||||||
|
{ "i-universal1:", btUniversals[ 1 ] },
|
||||||
|
{ "i-universal2:", btUniversals[ 2 ] },
|
||||||
|
{ "i-universal3:", btUniversals[ 3 ] },
|
||||||
|
{ "i-universal4:", btUniversals[ 4 ] },
|
||||||
|
{ "i-universal5:", btUniversals[ 5 ] },
|
||||||
|
{ "i-universal6:", btUniversals[ 6 ] },
|
||||||
|
{ "i-universal7:", btUniversals[ 7 ] },
|
||||||
|
{ "i-universal8:", btUniversals[ 8 ] },
|
||||||
|
{ "i-universal9:", btUniversals[ 9 ] }
|
||||||
};
|
};
|
||||||
auto lookup = lights.find( Label );
|
auto lookup = lights.find( Label );
|
||||||
if( lookup != lights.end() ) {
|
if( lookup != lights.end() ) {
|
||||||
|
|||||||
1
Train.h
1
Train.h
@@ -507,6 +507,7 @@ public: // reszta może by?publiczna
|
|||||||
TButton btLampkaHamowanie2zes;
|
TButton btLampkaHamowanie2zes;
|
||||||
TButton btLampkaOpory;
|
TButton btLampkaOpory;
|
||||||
TButton btLampkaWysRozr;
|
TButton btLampkaWysRozr;
|
||||||
|
std::array<TButton, 10> btUniversals; // NOTE: temporary arrangement until we have dynamically built control table
|
||||||
TButton btInstrumentLight;
|
TButton btInstrumentLight;
|
||||||
TButton btDashboardLight;
|
TButton btDashboardLight;
|
||||||
TButton btTimetableLight;
|
TButton btTimetableLight;
|
||||||
|
|||||||
@@ -1122,6 +1122,7 @@ driver_mode::InOutKey()
|
|||||||
|
|
||||||
if( train == nullptr ) {
|
if( train == nullptr ) {
|
||||||
FreeFlyModeFlag = true; // nadal poza kabiną
|
FreeFlyModeFlag = true; // nadal poza kabiną
|
||||||
|
Camera.m_owner = nullptr; // detach camera from the vehicle
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
renderer.cpp
14
renderer.cpp
@@ -836,9 +836,14 @@ void opengl_renderer::Render_pass(rendermode const Mode)
|
|||||||
// creates dynamic environment cubemap
|
// creates dynamic environment cubemap
|
||||||
bool opengl_renderer::Render_reflections()
|
bool opengl_renderer::Render_reflections()
|
||||||
{
|
{
|
||||||
|
if (Global.ReflectionUpdatesPerSecond == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
auto const &time = simulation::Time.data();
|
auto const &time = simulation::Time.data();
|
||||||
auto const timestamp = time.wDay * 24 * 60 + time.wHour * 60 + time.wMinute;
|
auto const timestamp = time.wMilliseconds + time.wSecond * 1000 + time.wMinute * 1000 * 60 + time.wHour * 1000 * 60 * 60;
|
||||||
if ((timestamp - m_environmentupdatetime < 1) && (glm::length(m_renderpass.camera.position() - m_environmentupdatelocation) < 1000.0))
|
|
||||||
|
if ((timestamp - m_environmentupdatetime < Global.ReflectionUpdatesPerSecond)
|
||||||
|
&& (glm::length(m_renderpass.camera.position() - m_environmentupdatelocation) < 1000.0))
|
||||||
{
|
{
|
||||||
// run update every 5+ mins of simulation time, or at least 1km from the last location
|
// run update every 5+ mins of simulation time, or at least 1km from the last location
|
||||||
return false;
|
return false;
|
||||||
@@ -2445,6 +2450,7 @@ void opengl_renderer::Render(TSubModel *Submodel)
|
|||||||
// we're capping how much effect the distance attenuation can have, otherwise the lights get too tiny at regular distances
|
// we're capping how much effect the distance attenuation can have, otherwise the lights get too tiny at regular distances
|
||||||
float const distancefactor{std::max(0.5f, (Submodel->fSquareMaxDist - TSubModel::fSquareDist) / Submodel->fSquareMaxDist)};
|
float const distancefactor{std::max(0.5f, (Submodel->fSquareMaxDist - TSubModel::fSquareDist) / Submodel->fSquareMaxDist)};
|
||||||
auto const pointsize{std::max(3.f, 5.f * distancefactor * anglefactor)};
|
auto const pointsize{std::max(3.f, 5.f * distancefactor * anglefactor)};
|
||||||
|
auto const resolutionratio { Global.iWindowHeight / 1080.f };
|
||||||
// additionally reduce light strength for farther sources in rain or snow
|
// additionally reduce light strength for farther sources in rain or snow
|
||||||
if (Global.Overcast > 0.75f)
|
if (Global.Overcast > 0.75f)
|
||||||
{
|
{
|
||||||
@@ -2478,14 +2484,14 @@ void opengl_renderer::Render(TSubModel *Submodel)
|
|||||||
{
|
{
|
||||||
// fake fog halo
|
// fake fog halo
|
||||||
float const fogfactor{interpolate(2.f, 1.f, clamp<float>(Global.fFogEnd / 2000, 0.f, 1.f)) * std::max(1.f, Global.Overcast)};
|
float const fogfactor{interpolate(2.f, 1.f, clamp<float>(Global.fFogEnd / 2000, 0.f, 1.f)) * std::max(1.f, Global.Overcast)};
|
||||||
model_ubs.param[1].x = pointsize * fogfactor * 2.0f;
|
model_ubs.param[1].x = pointsize * resolutionratio * fogfactor * 2.0f;
|
||||||
model_ubs.param[0] = glm::vec4(glm::vec3(lightcolor), Submodel->fVisible * std::min(1.f, lightlevel) * 0.5f);
|
model_ubs.param[0] = glm::vec4(glm::vec3(lightcolor), Submodel->fVisible * std::min(1.f, lightlevel) * 0.5f);
|
||||||
|
|
||||||
glDepthMask(GL_FALSE);
|
glDepthMask(GL_FALSE);
|
||||||
draw(Submodel->m_geometry);
|
draw(Submodel->m_geometry);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
}
|
}
|
||||||
model_ubs.param[1].x = pointsize * 2.0f;
|
model_ubs.param[1].x = pointsize * resolutionratio * 2.0f;
|
||||||
model_ubs.param[0] = glm::vec4(glm::vec3(lightcolor), Submodel->fVisible * std::min(1.f, lightlevel));
|
model_ubs.param[0] = glm::vec4(glm::vec3(lightcolor), Submodel->fVisible * std::min(1.f, lightlevel));
|
||||||
|
|
||||||
draw(Submodel->m_geometry);
|
draw(Submodel->m_geometry);
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ init() {
|
|||||||
u8"Nastawnik: %2d+%d %c%s",
|
u8"Nastawnik: %2d+%d %c%s",
|
||||||
u8" Prędkość: %d km/h (limit %d km/h%s)%s",
|
u8" Prędkość: %d km/h (limit %d km/h%s)%s",
|
||||||
u8", nowy limit: %d km/h za %.1f km",
|
u8", nowy limit: %d km/h za %.1f km",
|
||||||
u8" Pochylenie: %.1f%%%%",
|
u8" Nachylenie: %.1f%%%%",
|
||||||
u8"Hamulce: %4.1f+%-2.0f%c%s",
|
u8"Hamulce: %4.1f+%-2.0f%c%s",
|
||||||
u8" Ciśnienie: %.2f kPa (przewód główny: %.2f kPa)",
|
u8" Ciśnienie: %.2f kPa (przewód główny: %.2f kPa)",
|
||||||
u8"!CZUWAK! ",
|
u8"!CZUWAK! ",
|
||||||
|
|||||||
Reference in New Issue
Block a user