build 181231. cab control tweaks, python interpreter stderr initialization fail fallback, enabled cab reflections, more parameters exposed to python scripts, minor ai logic enhancements, minor debug enhancements

This commit is contained in:
tmj-fstate
2018-12-31 22:00:58 +01:00
parent 44a104bbd6
commit bdbbaafc83
14 changed files with 140 additions and 62 deletions

View File

@@ -836,7 +836,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
double v; // prędkość
double d; // droga
double d_to_next_sem = 10000.0; //ustaiwamy na pewno dalej niż widzi AI
bool isatpassengerstop { false }; // true if the consist is within acceptable range of w4 post
IsAtPassengerStop = false;
TCommandType go = TCommandType::cm_Unknown;
eSignNext = NULL;
// te flagi są ustawiane tutaj, w razie potrzeby
@@ -924,7 +924,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
sSpeedTable[i].iFlags = 0;
}
}
isatpassengerstop = (
IsAtPassengerStop = (
( sSpeedTable[ i ].fDist <= passengerstopmaxdistance )
// Ra 2F1I: odległość plus długość pociągu musi być mniejsza od długości
// peronu, chyba że pociąg jest dłuższy, to wtedy minimalna.
@@ -944,7 +944,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
if( mvOccupied->Vel > 0.3 ) {
// jeśli jedzie (nie trzeba czekać, aż się drgania wytłumią - drzwi zamykane od 1.0) to będzie zatrzymanie
sSpeedTable[ i ].fVelNext = 0;
} else if( true == isatpassengerstop ) {
} else if( true == IsAtPassengerStop ) {
// jeśli się zatrzymał przy W4, albo stał w momencie zobaczenia W4
if( !AIControllFlag ) {
// w razie przełączenia na AI ma nie podciągać do W4, gdy użytkownik zatrzymał za daleko
@@ -1035,7 +1035,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// jeśli są dalsze stacje, czekamy do godziny odjazdu
if (TrainParams->IsTimeToGo(simulation::Time.data().wHour, simulation::Time.data().wMinute)) {
// z dalszą akcją czekamy do godziny odjazdu
isatpassengerstop = false;
IsAtPassengerStop = false;
// przy jakim dystansie (stanie licznika) ma przesunąć na następny postój
fLastStopExpDist = mvOccupied->DistCounter + 0.050 + 0.001 * fLength;
TrainParams->StationIndexInc(); // przejście do następnej
@@ -1376,7 +1376,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// 2014-02: jeśli stoi, a ma do przejechania kawałek, to niech jedzie
if( ( mvOccupied->Vel < 0.01 )
&& ( true == TestFlag( sSpeedTable[ i ].iFlags, ( spEnabled | spEvent | spPassengerStopPoint ) ) )
&& ( false == isatpassengerstop ) ) {
&& ( false == IsAtPassengerStop ) ) {
// ma podjechać bliżej - czy na pewno w tym miejscu taki warunek?
a = ( ( d > passengerstopmaxdistance ) || ( ( iDrivigFlags & moveStopCloser ) != 0 ) ?
fAcc :
@@ -1457,7 +1457,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
}
//analiza spisanych z tabelki ograniczeń i nadpisanie aktualnego
if( ( true == isatpassengerstop ) && ( mvOccupied->Vel < 0.01 ) ) {
if( ( true == IsAtPassengerStop ) && ( mvOccupied->Vel < 0.01 ) ) {
// if stopped at a valid passenger stop, hold there
fVelDes = 0.0;
}
@@ -1625,6 +1625,11 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche,
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;
}
}
// TrainParams=NewTrainParams;
// if (TrainParams)
@@ -1944,7 +1949,13 @@ void TController::AutoRewident()
0.25 );
if( mvOccupied->TrainType == dt_EZT ) {
fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
if( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) {
// HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors
fNominalAccThreshold = std::max( -0.60, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
}
else {
fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
}
fBrakeReaction = 0.25;
}
else if( mvOccupied->TrainType == dt_DMU ) {
@@ -2100,8 +2111,6 @@ bool TController::CheckVehicles(TOrders user)
Lights(
frontlights,
rearlights );
// nastawianie hamulca do jazdy pociągowej
AutoRewident();
}
else if (OrderCurrentGet() & (Shunt | Connect))
{
@@ -2134,6 +2143,10 @@ bool TController::CheckVehicles(TOrders user)
Lights( 0, light::headlight_right );
}
}
// nastawianie hamulca do jazdy pociągowej
if( OrderCurrentGet() & ( Obey_train | Shunt ) ) {
AutoRewident();
}
}
else { // gdy człowiek i gdy nastąpiło połącznie albo rozłączenie
// Ra 2014-02: lepiej tu niż w pętli obsługującej komendy, bo tam się zmieni informacja o składzie
@@ -2841,7 +2854,7 @@ bool TController::IncSpeed()
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 parallelmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 ) };
auto const useseriesmodevoltage { 0.80 * mvControlling->EnginePowerSource.CollectorParameters.MaxV };
auto const useseriesmodevoltage { mvControlling->EnginePowerSource.CollectorParameters.MaxV * ( IsHeavyCargoTrain ? 0.70 : 0.80 ) };
auto const useseriesmode = (
( mvControlling->Imax > mvControlling->ImaxLo )
|| ( fVoltage < useseriesmodevoltage )
@@ -3824,10 +3837,6 @@ TController::UpdateSituation(double dt) {
// indywidualne luzowanko
vehicle->BrakeReleaser( 1 );
}
if( ( vehicle->Power > 0.01 ) // jeśli ma silnik
&& ( vehicle->FuseFlag ) ) { // wywalony nadmiarowy
Need_TryAgain = true; // reset jak przy wywaleniu nadmiarowego
}
}
}
}
@@ -3838,6 +3847,10 @@ TController::UpdateSituation(double dt) {
// ciężar razy składowa styczna grawitacji
fAccGravity -= vehicle->TotalMassxg * dy * ( p->DirectionGet() == iDirection ? 1 : -1 );
}
if( ( vehicle->Power > 0.01 ) // jeśli ma silnik
&& ( vehicle->FuseFlag ) ) { // wywalony nadmiarowy
Need_TryAgain = true; // reset jak przy wywaleniu nadmiarowego
}
p = p->Next(); // pojazd podłączony z tyłu (patrząc od czoła)
}
@@ -4090,6 +4103,12 @@ TController::UpdateSituation(double dt) {
// dla nastawienia G koniecznie należy wydłużyć drogę na czas reakcji
fBrakeDist += 2 * mvOccupied->Vel;
}
if( ( mvOccupied->Vel > 0.05 )
&& ( mvControlling->EngineType == TEngineType::ElectricInductionMotor )
&& ( ( mvControlling->TrainType & dt_EZT ) != 0 ) ) {
// HACK: make the induction motor powered EMUs start braking slightly earlier
fBrakeDist += 10.0;
}
/*
// take into account effect of gravity (but to stay on safe side of calculations, only downhill)
if( fAccGravity > 0.025 ) {
@@ -4746,8 +4765,8 @@ TController::UpdateSituation(double dt) {
fMinProximityDist : // cars can bunch up tighter
fMaxProximityDist ) ); // other vehicle types less so
*/
double k = coupler->Connected->Vel; // prędkość pojazdu z przodu (zakładając,
// że jedzie w tę samą stronę!!!)
// prędkość pojazdu z przodu (zakładając, że jedzie w tę samą stronę!!!)
double k = coupler->Connected->Vel;
if( k - vel < 5 ) {
// porównanie modułów prędkości [km/h]
// zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej
@@ -4755,6 +4774,26 @@ TController::UpdateSituation(double dt) {
ActualProximityDist,
vehicle->fTrackBlock );
if( ActualProximityDist <= (
( mvOccupied->CategoryFlag & 2 ) ?
100.0 : // cars
250.0 ) ) { // others
// regardless of driving mode at close distance take precaution measures:
// match the other vehicle's speed or slow down if the other vehicle is stopped
VelDesired =
min_speed(
VelDesired,
std::max(
k,
( mvOccupied->CategoryFlag & 2 ) ?
40.0 : // cars
20.0 ) ); // others
if( vel > VelDesired + fVelPlus ) {
// if going too fast force some prompt braking
AccPreferred = std::min( -0.65, AccPreferred );
}
}
double const distance = vehicle->fTrackBlock - fMaxProximityDist - ( fBrakeDist * 1.15 ); // odległość bezpieczna zależy od prędkości
if( distance < 0.0 ) {
// jeśli odległość jest zbyt mała
@@ -4804,7 +4843,7 @@ TController::UpdateSituation(double dt) {
}
}
ReactionTime = (
vel != 0.0 ?
mvOccupied->Vel > 0.01 ?
0.1 : // orientuj się, bo jest goraco
2.0 ); // we're already standing still, so take it easy
}

View File

@@ -261,6 +261,7 @@ private:
int iDriverFailCount = 0; // licznik błędów AI
bool Need_TryAgain = false; // true, jeśli druga pozycja w elektryku nie załapała
bool Need_BrakeRelease = true;
bool IsAtPassengerStop{ false }; // true if the consist is within acceptable range of w4 post
double fMinProximityDist = 30.0; // stawanie między 30 a 60 m przed przeszkodą // minimalna oległość do przeszkody, jaką należy zachować
double fOverhead1 = 3000.0; // informacja o napięciu w sieci trakcyjnej (0=brak drutu, zatrzymaj!)
double fOverhead2 = -1.0; // informacja o sposobie jazdy (-1=normalnie, 0=bez prądu, >0=z opuszczonym i ograniczeniem prędkości)

View File

@@ -563,7 +563,7 @@ bool TMoverParameters::DirectionForward()
SendCtrlToNext("Direction", ActiveDir, CabNo);
return true;
}
else if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType == TEngineType::ElectricSeriesMotor))
else if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor))
return MinCurrentSwitch(true); //"wysoki rozruch" EN57
return false;
};
@@ -635,8 +635,9 @@ bool TMoverParameters::ChangeCab(int direction)
{
// if (ActiveCab+direction=0) then LastCab:=ActiveCab;
ActiveCab = ActiveCab + direction;
if ((BrakeSystem == TBrakeSystem::Pneumatic) && (BrakeCtrlPosNo > 0))
{
if( ( BrakeCtrlPosNo > 0 )
&& ( ( BrakeSystem == TBrakeSystem::Pneumatic )
|| ( BrakeSystem == TBrakeSystem::ElectroPneumatic ) ) ) {
// if (BrakeHandle==FV4a) //!!!POBIERAĆ WARTOŚĆ Z KLASY ZAWORU!!!
// BrakeLevelSet(-2); //BrakeCtrlPos=-2;
// else if ((BrakeHandle==FVel6)||(BrakeHandle==St113))
@@ -2389,7 +2390,7 @@ bool TMoverParameters::EpFuseSwitch(bool State)
bool TMoverParameters::DirectionBackward(void)
{
bool DB = false;
if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType == TEngineType::ElectricSeriesMotor))
if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor))
if (MinCurrentSwitch(false))
{
DB = true; //
@@ -3555,9 +3556,8 @@ void TMoverParameters::UpdatePipePressure(double dt)
dpMainValve = 0;
if ((BrakeCtrlPosNo > 1) /*&& (ActiveCab != 0)*/)
// with BrakePressureTable[BrakeCtrlPos] do
{
if( BrakeCtrlPosNo > 1 ) {
if ((EngineType != TEngineType::ElectricInductionMotor))
dpLocalValve = LocHandle->GetPF(std::max(LocalBrakePosA, LocalBrakePosAEIM), Hamulec->GetBCP(), ScndPipePress, dt, 0);
else
@@ -3573,13 +3573,21 @@ void TMoverParameters::UpdatePipePressure(double dt)
temp = ScndPipePress;
}
Handle->SetReductor(BrakeCtrlPos2);
if( ( ( BrakeOpModes & bom_PS ) == 0 )
|| ( ( ActiveCab != 0 )
&& ( BrakeOpModeFlag != bom_PS ) ) ) {
if ((BrakeOpModeFlag != bom_PS))
if ((BrakeOpModeFlag < bom_EP) || ((Handle->GetPos(bh_EB) - 0.5) < BrakeCtrlPosR) ||
(BrakeHandle != TBrakeHandle::MHZ_EN57))
dpMainValve = Handle->GetPF(BrakeCtrlPosR, PipePress, temp, dt, EqvtPipePress);
else
dpMainValve = Handle->GetPF(0, PipePress, temp, dt, EqvtPipePress);
if( ( BrakeOpModeFlag < bom_EP )
|| ( ( Handle->GetPos( bh_EB ) - 0.5 ) < BrakeCtrlPosR )
|| ( ( BrakeHandle != TBrakeHandle::MHZ_EN57 )
&& ( BrakeHandle != TBrakeHandle::MHZ_K8P ) ) ) {
dpMainValve = Handle->GetPF( BrakeCtrlPosR, PipePress, temp, dt, EqvtPipePress );
}
else {
dpMainValve = Handle->GetPF( 0, PipePress, temp, dt, EqvtPipePress );
}
}
if (dpMainValve < 0) // && (PipePressureVal > 0.01) //50
if (Compressor > ScndPipePress)
@@ -5528,8 +5536,9 @@ bool TMoverParameters::MaxCurrentSwitch(bool State)
bool TMoverParameters::MinCurrentSwitch(bool State)
{
bool MCS = false;
if (((EngineType == TEngineType::ElectricSeriesMotor) && (IminHi > IminLo)) || (TrainType == dt_EZT))
{
if( ( ( EngineType == TEngineType::ElectricSeriesMotor ) && ( IminHi > IminLo ) )
|| ( ( TrainType == dt_EZT ) && ( EngineType != TEngineType::ElectricInductionMotor ) ) ) {
if (State && (Imin == IminLo))
{
Imin = IminHi;

View File

@@ -90,13 +90,11 @@ auto python_taskqueue::init() -> bool {
stringioclassname != nullptr ?
PyObject_CallObject( stringioclassname, nullptr ) :
nullptr ) };
m_error = { (
m_stderr = { (
stringioobject == nullptr ? nullptr :
PySys_SetObject( "stderr", stringioobject ) != 0 ? nullptr :
stringioobject ) };
if( m_error == nullptr ) { goto release_and_exit; }
if( false == run_file( "abstractscreenrenderer" ) ) { goto release_and_exit; }
// release the lock, save the state for future use
@@ -315,13 +313,13 @@ python_taskqueue::error() {
if( PyErr_Occurred() == nullptr ) { return; }
if( m_error != nullptr ) {
if( m_stderr != nullptr ) {
// std err pythona jest buforowane
PyErr_Print();
auto *errortext { PyObject_CallMethod( m_error, "getvalue", nullptr ) };
auto *errortext { PyObject_CallMethod( m_stderr, "getvalue", nullptr ) };
ErrorLog( PyString_AsString( errortext ) );
// czyscimy bufor na kolejne bledy
PyObject_CallMethod( m_error, "truncate", "i", 0 );
PyObject_CallMethod( m_stderr, "truncate", "i", 0 );
}
else {
// nie dziala buffor pythona
@@ -343,7 +341,7 @@ python_taskqueue::error() {
}
auto *tracebacktext { PyObject_Str( traceback ) };
if( tracebacktext != nullptr ) {
WriteLog( PyString_AsString( tracebacktext ) );
ErrorLog( PyString_AsString( tracebacktext ) );
}
else {
WriteLog( "Python Interpreter: failed to retrieve the stack traceback" );

View File

@@ -83,7 +83,7 @@ private:
void error();
// members
PyObject *m_main { nullptr };
PyObject *m_error { nullptr };
PyObject *m_stderr { nullptr };
PyThreadState *m_mainthread{ nullptr };
worker_array m_workers;
threading::condition_variable m_condition; // wakes up the workers

View File

@@ -543,13 +543,18 @@ PyObject *TTrain::GetTrainState() {
PyDict_SetItemString( dict, "velnext", PyGetFloat( driver->VelNext ) );
PyDict_SetItemString( dict, "actualproximitydist", PyGetFloat( driver->ActualProximityDist ) );
// train data
auto const *timetable{ driver->TrainTimetable() };
PyDict_SetItemString( dict, "trainnumber", PyGetString( driver->TrainName().c_str() ) );
PyDict_SetItemString( dict, "train_brakingmassratio", PyGetFloat( timetable->BrakeRatio ) );
PyDict_SetItemString( dict, "train_enginetype", PyGetString( timetable->LocSeries.c_str() ) );
PyDict_SetItemString( dict, "train_engineload", PyGetFloat( timetable->LocLoad ) );
PyDict_SetItemString( dict, "train_stationindex", PyGetInt( driver->StationIndex() ) );
auto const stationcount { driver->StationCount() };
PyDict_SetItemString( dict, "train_stationcount", PyGetInt( stationcount ) );
if( stationcount > 0 ) {
// timetable stations data, if there's any
auto const *timetable { driver->TrainTimetable() };
for( auto stationidx = 1; stationidx <= stationcount; ++stationidx ) {
auto const stationlabel { "train_station" + std::to_string( stationidx ) + "_" };
auto const &timetableline { timetable->TimeTable[ stationidx ] };
@@ -563,7 +568,9 @@ PyObject *TTrain::GetTrainState() {
PyDict_SetItemString( dict, ( stationlabel + "dm" ).c_str(), PyGetInt( timetableline.Dm ) );
}
}
PyDict_SetItemString( dict, "train_atpassengerstop", PyGetBool( driver->IsAtPassengerStop ) );
// world state data
PyDict_SetItemString( dict, "scenario", PyGetString( Global.SceneryFile.c_str() ) );
PyDict_SetItemString( dict, "hours", PyGetInt( simulation::Time.data().wHour ) );
PyDict_SetItemString( dict, "minutes", PyGetInt( simulation::Time.data().wMinute ) );
PyDict_SetItemString( dict, "seconds", PyGetInt( simulation::Time.second() ) );
@@ -1367,13 +1374,11 @@ void TTrain::OnCommand_trainbrakeoperationmodeincrease(TTrain *Train, command_da
if( ( ( Train->mvOccupied->BrakeOpModeFlag << 1 ) & Train->mvOccupied->BrakeOpModes ) != 0 ) {
// next mode
Train->mvOccupied->BrakeOpModeFlag <<= 1;
// audio feedback
Train->dsbPneumaticSwitch.play();
// visual feedback
Train->ggBrakeOperationModeCtrl.UpdateValue(
Train->mvOccupied->BrakeOpModeFlag > 0 ?
std::log2( Train->mvOccupied->BrakeOpModeFlag ) :
0 );
0 ); // audio fallback
}
}
}
@@ -1385,8 +1390,6 @@ void TTrain::OnCommand_trainbrakeoperationmodedecrease(TTrain *Train, command_da
if( ( ( Train->mvOccupied->BrakeOpModeFlag >> 1 ) & Train->mvOccupied->BrakeOpModes ) != 0 ) {
// previous mode
Train->mvOccupied->BrakeOpModeFlag >>= 1;
// audio feedback
Train->dsbPneumaticSwitch.play();
// visual feedback
Train->ggBrakeOperationModeCtrl.UpdateValue(
Train->mvOccupied->BrakeOpModeFlag > 0 ?
@@ -5443,8 +5446,8 @@ bool TTrain::Update( double const Deltatime )
btLampkaRadioStop.Turn( mvOccupied->Radio && mvOccupied->RadioStopFlag );
btLampkaHamulecReczny.Turn(mvOccupied->ManualBrakePos > 0);
// NBMX wrzesien 2003 - drzwi oraz sygnał odjazdu
btLampkaDoorLeft.Turn(mvOccupied->DoorLeftOpened);
btLampkaDoorRight.Turn(mvOccupied->DoorRightOpened);
btLampkaDoorLeft.Turn( DynamicObject->dDoorMoveL > 0.0 );// mvOccupied->DoorLeftOpened);
btLampkaDoorRight.Turn( DynamicObject->dDoorMoveR > 0.0 ); //mvOccupied ->DoorRightOpened);
btLampkaBlokadaDrzwi.Turn(mvOccupied->DoorBlockedFlag());
btLampkaDoorLockOff.Turn( false == mvOccupied->DoorLockEnabled );
btLampkaDepartureSignal.Turn( mvControlled->DepartureSignal );
@@ -5754,7 +5757,12 @@ bool TTrain::Update( double const Deltatime )
InstrumentLightType == 0 ? mvControlled->Battery || mvControlled->ConverterFlag :
InstrumentLightType == 1 ? mvControlled->Mains :
InstrumentLightType == 2 ? mvControlled->ConverterFlag :
InstrumentLightType == 3 ? mvControlled->Battery || mvControlled->ConverterFlag :
false ) };
if( InstrumentLightType == 3 ) {
// TODO: link the light state with the state of the master key
InstrumentLightActive = true;
}
btInstrumentLight.Turn( InstrumentLightActive && lightpower );
btDashboardLight.Turn( DashboardLightActive && lightpower );
btTimetableLight.Turn( TimetableLightActive && lightpower );
@@ -5812,7 +5820,9 @@ bool TTrain::Update( double const Deltatime )
ggHornLowButton.Update();
ggHornHighButton.Update();
ggWhistleButton.Update();
ggHelperButton.UpdateValue(DynamicObject->Mechanik->HelperState);
if( DynamicObject->Mechanik != nullptr ) {
ggHelperButton.UpdateValue( DynamicObject->Mechanik->HelperState );
}
ggHelperButton.Update();
for( auto &universal : ggUniversals ) {
universal.Update();
@@ -5880,7 +5890,8 @@ bool TTrain::Update( double const Deltatime )
// NOTE: crude way to have the pantographs go back up if they're dropped due to insufficient pressure etc
// TODO: rework it into something more elegant, when redoing the whole consist/unit/cab etc arrangement
if( false == DynamicObject->Mechanik->AIControllFlag ) {
if( ( DynamicObject->Mechanik == nullptr )
|| ( false == DynamicObject->Mechanik->AIControllFlag ) ) {
// don't mess with the ai driving, at least not while switches don't follow ai-set vehicle state
if( ( mvControlled->Battery )
|| ( mvControlled->ConverterFlag ) ) {
@@ -7298,8 +7309,8 @@ void TTrain::set_cab_controls( int const Cab ) {
0.f ) );
// doors
// NOTE: we're relying on the cab models to have switches reversed for the rear cab(?)
ggDoorLeftButton.PutValue( mvOccupied->DoorLeftOpened ? 1.f : 0.f );
ggDoorRightButton.PutValue( mvOccupied->DoorRightOpened ? 1.f : 0.f );
ggDoorLeftButton.PutValue( /*mvOccupied->DoorLeftOpened*/ DynamicObject->dDoorMoveL > 0.0 ? 1.f : 0.f );
ggDoorRightButton.PutValue( /*mvOccupied->DoorRightOpened*/ DynamicObject->dDoorMoveR > 0.0 ? 1.f : 0.f );
// door lock
ggDoorSignallingButton.PutValue(
mvOccupied->DoorLockEnabled ?
@@ -7505,14 +7516,18 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
btInstrumentLight.Load( Parser, DynamicObject );
InstrumentLightType = 0;
}
else if( Label == "i-instrumentlight_M:" ) {
else if( Label == "i-instrumentlight_m:" ) {
btInstrumentLight.Load( Parser, DynamicObject );
InstrumentLightType = 1;
}
else if( Label == "i-instrumentlight_C:" ) {
else if( Label == "i-instrumentlight_c:" ) {
btInstrumentLight.Load( Parser, DynamicObject );
InstrumentLightType = 2;
}
else if( Label == "i-instrumentlight_a:" ) {
btInstrumentLight.Load( Parser, DynamicObject );
InstrumentLightType = 3;
}
else if (Label == "i-doors:")
{
int i = Parser.getToken<int>() - 1;
@@ -7748,6 +7763,12 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
gauge.Load(Parser, DynamicObject, 0.1);
gauge.AssignDouble(&mvOccupied->PipePress);
}
else if( Label == "scndpress:" ) {
// manometr przewodu hamulcowego
auto &gauge = Cabine[ Cabindex ].Gauge( -1 ); // pierwsza wolna gałka
gauge.Load( Parser, DynamicObject, 0.1 );
gauge.AssignDouble( &mvOccupied->ScndPipePress );
}
else if (Label == "limpipepress:")
{
// manometr zbiornika sterujacego zaworu maszynisty

View File

@@ -508,7 +508,7 @@ public: // reszta może by?publiczna
TButton btInstrumentLight;
TButton btDashboardLight;
TButton btTimetableLight;
int InstrumentLightType{ 0 }; // ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw.
int InstrumentLightType{ 0 }; // ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw., 3-rozrzad
bool InstrumentLightActive{ false };
bool DashboardLightActive{ false };
bool TimetableLightActive{ false };

View File

@@ -443,8 +443,8 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
std::abs( mover.enrot ) * 60,
std::abs( mover.nrot ) * mover.Transmision.Ratio * 60,
mover.RventRot * 60,
mover.MotorBlowers[side::front].revolutions,
mover.MotorBlowers[side::rear].revolutions,
std::abs( mover.MotorBlowers[side::front].revolutions ),
std::abs( mover.MotorBlowers[side::rear].revolutions ),
mover.dizel_heat.rpmw,
mover.dizel_heat.rpmw2 );
@@ -470,6 +470,7 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
// brakes
mover.fBrakeCtrlPos,
mover.LocalBrakePosA,
mover.BrakeOpModeFlag,
update_vehicle_brake().c_str(),
mover.LoadFlag,
// cylinders
@@ -482,7 +483,7 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
mover.ScndPipePress,
mover.CntrlPipePress,
// tanks
mover.Volume,
mover.Hamulec->GetBRP(),
mover.Compressor,
mover.Hamulec->GetCRP() );

View File

@@ -554,7 +554,9 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
// without rain/snow we can render the cab early to limit the overdraw
if( ( false == FreeFlyModeFlag )
&& ( Global.Overcast <= 1.f ) ) { // precipitation happens when overcast is in 1-2 range
#ifdef EU07_DISABLECABREFLECTIONS
switch_units( true, true, false );
#endif
setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix );
// cache shadow colour in case we need to account for cab light
auto const shadowcolor { m_shadowcolor };
@@ -577,7 +579,9 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
Render_precipitation();
// cab render
if( false == FreeFlyModeFlag ) {
#ifdef EU07_DISABLECABREFLECTIONS
switch_units( true, true, false );
#endif
setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix );
// cache shadow colour in case we need to account for cab light
auto const shadowcolor{ m_shadowcolor };

View File

@@ -26,6 +26,7 @@ http://mozilla.org/MPL/2.0/.
//#define EU07_USE_DEBUG_CAMERA
//#define EU07_USE_DEBUG_SOUNDEMITTERS
//#define EU07_USEIMGUIIMPLOPENGL2
//#define EU07_DISABLECABREFLECTIONS
struct opengl_light : public basic_light {

View File

@@ -36,7 +36,7 @@ scenarioloader_mode::init() {
bool
scenarioloader_mode::update() {
WriteLog( "\nLoading scenario..." );
WriteLog( "\nLoading scenario \"" + Global.SceneryFile + "\"..." );
auto timestart = std::chrono::system_clock::now();

View File

@@ -57,7 +57,7 @@ init() {
"Controllers:\n master: %d(%d), secondary: %s\nEngine output: %.1f, current: %.0f\nRevolutions:\n engine: %.0f, motors: %.0f\n engine fans: %.0f, motor fans: %.0f+%.0f, cooling fans: %.0f+%.0f",
" (shunt mode)",
"\nTemperatures:\n engine: %.2f, oil: %.2f, water: %.2f%c%.2f",
"Brakes:\n train: %.2f, independent: %.2f, delay: %s, load flag: %d\nBrake cylinder pressures:\n train: %.2f, independent: %.2f, status: 0x%.2x\nPipe pressures:\n brake: %.2f (hat: %.2f), main: %.2f, control: %.2f\nTank pressures:\n auxiliary: %.2f, main: %.2f, control: %.2f",
"Brakes:\n train: %.2f, independent: %.2f, mode: %d, delay: %s, load flag: %d\nBrake cylinder pressures:\n train: %.2f, independent: %.2f, status: 0x%.2x\nPipe pressures:\n brake: %.2f (hat: %.2f), main: %.2f, control: %.2f\nTank pressures:\n auxiliary: %.2f, main: %.2f, control: %.2f",
" pantograph: %.2f%cMT",
"Forces:\n tractive: %.1f, brake: %.1f, friction: %.2f%s\nAcceleration:\n tangential: %.2f, normal: %.2f (path radius: %s)\nVelocity: %.2f, distance traveled: %.2f\nPosition: [%.2f, %.2f, %.2f]",
@@ -72,6 +72,7 @@ init() {
"brake acting speed",
"brake acting speed: cargo",
"brake acting speed: rapid",
"brake operation mode",
"motor overload relay threshold",
"water pump",
"water pump breaker",
@@ -194,7 +195,7 @@ init() {
"Nastawniki:\n glowny: %d(%d), dodatkowy: %s\nMoc silnika: %.1f, prad silnika: %.0f\nObroty:\n silnik: %.0f, motory: %.0f\n went.silnika: %.0f, went.motorow: %.0f+%.0f, went.chlodnicy: %.0f+%.0f",
" (tryb manewrowy)",
"\nTemperatury:\n silnik: %.2f, olej: %.2f, woda: %.2f%c%.2f",
"Hamulce:\n zespolony: %.2f, pomocniczy: %.2f, nastawa: %s, ladunek: %d\nCisnienie w cylindrach:\n zespolony: %.2f, pomocniczy: %.2f, status: 0x%.2x\nCisnienia w przewodach:\n glowny: %.2f (kapturek: %.2f), zasilajacy: %.2f, kontrolny: %.2f\nCisnienia w zbiornikach:\n pomocniczy: %.2f, glowny: %.2f, sterujacy: %.2f",
"Hamulce:\n zespolony: %.2f, pomocniczy: %.2f, tryb: %d, nastawa: %s, ladunek: %d\nCisnienie w cylindrach:\n zespolony: %.2f, pomocniczy: %.2f, status: 0x%.2x\nCisnienia w przewodach:\n glowny: %.2f (kapturek: %.2f), zasilajacy: %.2f, kontrolny: %.2f\nCisnienia w zbiornikach:\n pomocniczy: %.2f, glowny: %.2f, sterujacy: %.2f",
" pantograf: %.2f%cZG",
"Sily:\n napedna: %.1f, hamowania: %.1f, tarcie: %.2f%s\nPrzyspieszenia:\n styczne: %.2f, normalne: %.2f (promien: %s)\nPredkosc: %.2f, pokonana odleglosc: %.2f\nPozycja: [%.2f, %.2f, %.2f]",
@@ -209,6 +210,7 @@ init() {
"nastawa hamulca",
"nastawa hamulca: towarowy",
"nastawa hamulca: pospieszny",
"tryb pracy hamulca",
"zakres pradu rozruchu",
"pompa wody",
"wylacznik samoczynny pompy wody",
@@ -318,6 +320,7 @@ init() {
"brakeprofile_sw:",
"brakeprofileg_sw:",
"brakeprofiler_sw:",
"brakeopmode_sw:",
"maxcurrent_sw:",
"waterpump_sw:",
"waterpumpbreaker_sw:",

View File

@@ -61,6 +61,7 @@ enum string {
cab_brakeprofile_sw,
cab_brakeprofileg_sw,
cab_brakeprofiler_sw,
cab_brakeopmode_sw,
cab_maxcurrent_sw,
cab_waterpump_sw,
cab_waterpumpbreaker_sw,

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 18
#define VERSION_MINOR 1223
#define VERSION_MINOR 1231
#define VERSION_REVISION 0