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

driver aid next speed limit enhancement, texture size check, cab controls tweaks, crash fix

This commit is contained in:
tmj-fstate
2020-07-05 23:16:31 +02:00
parent fccb1c6c16
commit 46bd8c6207
5 changed files with 107 additions and 27 deletions

View File

@@ -828,8 +828,7 @@ void TController::TableCheck(double fDistance)
typeid( *(sSpeedTable[i].evEvent) ) == typeid( putvalues_event ) ? typeid( *(sSpeedTable[i].evEvent) ) == typeid( putvalues_event ) ?
-fLength : -fLength :
0)) // jeśli jest z tyłu 0)) // jeśli jest z tyłu
if ((mvOccupied->CategoryFlag & 1) ? false : if ((mvOccupied->CategoryFlag == 2) && (sSpeedTable[i].fDist < -0.75))
sSpeedTable[i].fDist < -fLength)
{ // pociąg staje zawsze, a samochód tylko jeśli nie przejedzie całą długością (może być zaskoczony zmianą) { // pociąg staje zawsze, a samochód tylko jeśli nie przejedzie całą długością (może być zaskoczony zmianą)
// WriteLog("TableCheck: Event is behind. Delete from table: " + sSpeedTable[i].evEvent->asName); // WriteLog("TableCheck: Event is behind. Delete from table: " + sSpeedTable[i].evEvent->asName);
sSpeedTable[i].iFlags &= ~spEnabled; // degradacja pozycji dla samochodu; sSpeedTable[i].iFlags &= ~spEnabled; // degradacja pozycji dla samochodu;
@@ -1137,6 +1136,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
if( sSpeedTable[ i ].iFlags & spSwitch ) { if( sSpeedTable[ i ].iFlags & spSwitch ) {
// zwrotnice są usuwane z tabelki dopiero po zjechaniu z nich // zwrotnice są usuwane z tabelki dopiero po zjechaniu z nich
iDrivigFlags |= moveSwitchFound; // rozjazd z przodu/pod ogranicza np. sens skanowania wstecz iDrivigFlags |= moveSwitchFound; // rozjazd z przodu/pod ogranicza np. sens skanowania wstecz
SwitchClearDist = sSpeedTable[ i ].fDist + sSpeedTable[ i ].trTrack->Length() + fLength;
} }
else if (sSpeedTable[i].iFlags & spEvent) // W4 może się deaktywować else if (sSpeedTable[i].iFlags & spEvent) // W4 może się deaktywować
{ // jeżeli event, może być potrzeba wysłania komendy, aby ruszył { // jeżeli event, może być potrzeba wysłania komendy, aby ruszył
@@ -1453,6 +1453,9 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// ograniczenie aktualnej prędkości aż do wyjechania za ograniczenie // ograniczenie aktualnej prędkości aż do wyjechania za ograniczenie
fVelDes = v; fVelDes = v;
} }
if( v < VelLimitLastDist.first ) {
VelLimitLastDist.second = d + sSpeedTable[ i ].trTrack->Length() + fLength;
}
if( false == railwaytrackend ) if( false == railwaytrackend )
continue; // i tyle wystarczy continue; // i tyle wystarczy
} }
@@ -1483,7 +1486,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
} }
} }
if ((a < fAcc) && (v == std::min(v, fNext))) { if ((a < fAcc) && (v == min_speed(v, fNext))) {
// mniejsze przyspieszenie to mniejsza możliwość rozpędzenia się albo konieczność hamowania // mniejsze przyspieszenie to mniejsza możliwość rozpędzenia się albo konieczność hamowania
// jeśli droga wolna, to może być a>1.0 i się tu nie załapuje // jeśli droga wolna, to może być a>1.0 i się tu nie załapuje
fAcc = a; // zalecane przyspieszenie (nie musi być uwzględniane przez AI) fAcc = a; // zalecane przyspieszenie (nie musi być uwzględniane przez AI)
@@ -1495,6 +1498,14 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
fNext = v; // istotna jest prędkość na końcu tego odcinka fNext = v; // istotna jest prędkość na końcu tego odcinka
fDist = d; // dlugość odcinka (kolejne pozycje mogą wydłużać drogę, jeśli prędkość jest stała) fDist = d; // dlugość odcinka (kolejne pozycje mogą wydłużać drogę, jeśli prędkość jest stała)
} }
if( ( v < VelLimitLastDist.first ) /* && ( d < VelLimitLastDist.second ) */ ) {
// if we encounter another speed limit before we can clear current/last registered one,
// update our calculation where we'll be able to resume regular speed
VelLimitLastDist.second = d + fLength;
if( ( sSpeedTable[ i ].iFlags & spTrack ) != 0 ) {
VelLimitLastDist.second += sSpeedTable[ i ].trTrack->Length();
}
}
} // if (v>=0.0) } // if (v>=0.0)
if (fNext >= 0.0) if (fNext >= 0.0)
{ // jeśli ograniczenie { // jeśli ograniczenie
@@ -1513,6 +1524,10 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
&& ( true == TestFlag( OrderCurrentGet(), Obey_train ) ) ) { && ( true == TestFlag( OrderCurrentGet(), Obey_train ) ) ) {
VelSignalLast = -1.0; VelSignalLast = -1.0;
} }
if( ( VelSignalLast >= 0.0 ) && ( SwitchClearDist >= 0.0 ) ) {
// take into account the effect switches have on duration of signal-imposed speed limit, in calculation of speed limit end point
VelLimitLastDist.second = std::max( VelLimitLastDist.second, SwitchClearDist );
}
//analiza spisanych z tabelki ograniczeń i nadpisanie aktualnego //analiza spisanych z tabelki ograniczeń i nadpisanie aktualnego
if( ( true == IsAtPassengerStop ) && ( mvOccupied->Vel < 0.01 ) ) { if( ( true == IsAtPassengerStop ) && ( mvOccupied->Vel < 0.01 ) ) {
@@ -5582,6 +5597,8 @@ TController::UpdateSituation(double dt) {
AccDesired = AccPreferred; // AccPreferred wynika z osobowości mechanika AccDesired = AccPreferred; // AccPreferred wynika z osobowości mechanika
VelNext = VelDesired; // maksymalna prędkość wynikająca z innych czynników niż trajektoria ruchu VelNext = VelDesired; // maksymalna prędkość wynikająca z innych czynników niż trajektoria ruchu
ActualProximityDist = routescanrange; // funkcja Update() może pozostawić wartości bez zmian ActualProximityDist = routescanrange; // funkcja Update() może pozostawić wartości bez zmian
VelLimitLastDist = { VelDesired, -1 };
SwitchClearDist = -1;
// Ra: odczyt (ActualProximityDist), (VelNext) i (AccPreferred) z tabelki prędkosci // Ra: odczyt (ActualProximityDist), (VelNext) i (AccPreferred) z tabelki prędkosci
TCommandType comm = TableUpdate(VelDesired, ActualProximityDist, VelNext, AccDesired); TCommandType comm = TableUpdate(VelDesired, ActualProximityDist, VelNext, AccDesired);
@@ -5804,6 +5821,7 @@ TController::UpdateSituation(double dt) {
// mamy coś z przodu // mamy coś z przodu
// 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ę!!!)
auto const k { Obstacle.vehicle->MoverParameters->Vel }; auto const k { Obstacle.vehicle->MoverParameters->Vel };
if( k - vel < 5 ) { if( k - vel < 5 ) {
// porównanie modułów prędkości [km/h] // porównanie modułów prędkości [km/h]
// zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej // zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej

View File

@@ -300,6 +300,8 @@ private:
double VelRestricted = -1.0; // speed of travel after passing a permissive signal at stop double VelRestricted = -1.0; // speed of travel after passing a permissive signal at stop
double FirstSemaphorDist = 10000.0; // odległość do pierwszego znalezionego semafora double FirstSemaphorDist = 10000.0; // odległość do pierwszego znalezionego semafora
double ActualProximityDist = 1.0; // odległość brana pod uwagę przy wyliczaniu prędkości i przyspieszenia double ActualProximityDist = 1.0; // odległość brana pod uwagę przy wyliczaniu prędkości i przyspieszenia
std::pair<double, double> VelLimitLastDist { 0.0, 0.0 }; // distance to velocity change point
double SwitchClearDist { 0.0 }; // distance to point after farthest detected switch
int iDirection = 0; // kierunek jazdy względem sprzęgów pojazdu, w którym siedzi AI (1=przód,-1=tył) int iDirection = 0; // kierunek jazdy względem sprzęgów pojazdu, w którym siedzi AI (1=przód,-1=tył)
int iDirectionOrder = 0; //żadany kierunek jazdy (służy do zmiany kierunku) int iDirectionOrder = 0; //żadany kierunek jazdy (służy do zmiany kierunku)
int iVehicleCount = -2; // wartość neutralna // ilość pojazdów do odłączenia albo zabrania ze składu (-1=wszystkie) int iVehicleCount = -2; // wartość neutralna // ilość pojazdów do odłączenia albo zabrania ze składu (-1=wszystkie)

View File

@@ -240,7 +240,7 @@ opengl_texture::load() {
} }
else { else {
WriteLog( "Loading texture data from \"" + name + type + "\"", logtype::texture ); WriteLog( "Loading texture data from \"" + name + "\"", logtype::texture );
data_state = resource_state::loading; data_state = resource_state::loading;
@@ -254,6 +254,16 @@ opengl_texture::load() {
// data state will be set by called loader, so we're all done here // data state will be set by called loader, so we're all done here
if( data_state == resource_state::good ) { if( data_state == resource_state::good ) {
// verify texture size
if( ( clamp_power_of_two( data_width ) != data_width ) || ( clamp_power_of_two( data_height ) != data_height ) ) {
if( name != "logo" ) {
WriteLog( "Warning: dimensions of texture \"" + name + "\" aren't powers of 2", logtype::texture );
}
}
if( ( quantize( data_width, 4 ) != data_width ) || ( quantize( data_height, 4 ) != data_height ) ) {
WriteLog( "Warning: dimensions of texture \"" + name + "\" aren't multiples of 4", logtype::texture );
}
has_alpha = ( has_alpha = (
data_components == GL_RGBA ? data_components == GL_RGBA ?
true : true :
@@ -266,7 +276,7 @@ opengl_texture::load() {
fail: fail:
data_state = resource_state::failed; data_state = resource_state::failed;
ErrorLog( "Bad texture: failed to load texture \"" + name + type + "\"" ); ErrorLog( "Bad texture: failed to load texture \"" + name + "\"" );
// NOTE: temporary workaround for texture assignment errors // NOTE: temporary workaround for texture assignment errors
id = 0; id = 0;
return; return;
@@ -275,8 +285,8 @@ fail:
void void
opengl_texture::make_stub() { opengl_texture::make_stub() {
data_width = 2; data_width = 4;
data_height = 2; data_height = 4;
data.resize( data_width * data_height * 3 ); data.resize( data_width * data_height * 3 );
std::fill( std::begin( data ), std::end( data ), static_cast<char>( 0xc0 ) ); std::fill( std::begin( data ), std::end( data ), static_cast<char>( 0xc0 ) );
data_mapcount = 1; data_mapcount = 1;

View File

@@ -2142,7 +2142,13 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
// impulse switches return automatically to neutral position // impulse switches return automatically to neutral position
if( Train->mvOccupied->PantSwitchType == "impulse" ) { if( Train->mvOccupied->PantSwitchType == "impulse" ) {
Train->mvOccupied->OperatePantographValve( end::front, operation_t::none ); auto const ismanual { Train->mvOccupied->Pantographs[ end::front ].valve.start_type == start_t::manual };
Train->mvOccupied->OperatePantographValve(
end::front,
operation_t::none,
( ismanual ?
range_t::local :
range_t::consist ) );
} }
} }
} }
@@ -2168,7 +2174,13 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
// impulse switches return automatically to neutral position // impulse switches return automatically to neutral position
if( Train->mvOccupied->PantSwitchType == "impulse" ) { if( Train->mvOccupied->PantSwitchType == "impulse" ) {
Train->mvOccupied->OperatePantographValve( end::rear, operation_t::none ); auto const ismanual { Train->mvOccupied->Pantographs[ end::rear ].valve.start_type == start_t::manual };
Train->mvOccupied->OperatePantographValve(
end::rear,
operation_t::none,
( ismanual ?
range_t::local :
range_t::consist ) );
} }
} }
} }
@@ -2183,10 +2195,15 @@ void TTrain::OnCommand_pantographraisefront( TTrain *Train, command_data const &
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
Train->mvOccupied->OperatePantographValve( end::front, auto const ismanual { Train->mvOccupied->Pantographs[ end::front ].valve.start_type == start_t::manual };
Train->mvOccupied->PantSwitchType == "impulse" ? Train->mvOccupied->OperatePantographValve(
end::front,
( Train->mvOccupied->PantSwitchType == "impulse" ?
operation_t::enable_on : operation_t::enable_on :
operation_t::enable ); operation_t::enable ),
( ismanual ?
range_t::local :
range_t::consist ) );
} }
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
// NOTE: bit of a hax here, we're reusing button reset routine so we don't need a copy in every branch // NOTE: bit of a hax here, we're reusing button reset routine so we don't need a copy in every branch
@@ -2204,10 +2221,15 @@ void TTrain::OnCommand_pantographraiserear( TTrain *Train, command_data const &C
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
Train->mvOccupied->OperatePantographValve( end::rear, auto const ismanual { Train->mvOccupied->Pantographs[ end::rear ].valve.start_type == start_t::manual };
Train->mvOccupied->PantSwitchType == "impulse" ? Train->mvOccupied->OperatePantographValve(
end::rear,
( Train->mvOccupied->PantSwitchType == "impulse" ?
operation_t::enable_on : operation_t::enable_on :
operation_t::enable ); operation_t::enable ),
( ismanual ?
range_t::local :
range_t::consist ) );
} }
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
// NOTE: bit of a hax here, we're reusing button reset routine so we don't need a copy in every branch // NOTE: bit of a hax here, we're reusing button reset routine so we don't need a copy in every branch
@@ -2230,10 +2252,15 @@ void TTrain::OnCommand_pantographlowerfront( TTrain *Train, command_data const &
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
Train->mvOccupied->OperatePantographValve( end::front, auto const ismanual { Train->mvOccupied->Pantographs[ end::front ].valve.start_type == start_t::manual };
Train->mvOccupied->PantSwitchType == "impulse" ? Train->mvOccupied->OperatePantographValve(
end::front,
( Train->mvOccupied->PantSwitchType == "impulse" ?
operation_t::disable_on : operation_t::disable_on :
operation_t::disable ); operation_t::disable ),
( ismanual ?
range_t::local :
range_t::consist ) );
} }
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
// NOTE: bit of a hax here, we're reusing button reset routine so we don't need a copy in every branch // NOTE: bit of a hax here, we're reusing button reset routine so we don't need a copy in every branch
@@ -2255,10 +2282,15 @@ void TTrain::OnCommand_pantographlowerrear( TTrain *Train, command_data const &C
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
Train->mvOccupied->OperatePantographValve( end::rear, auto const ismanual { Train->mvOccupied->Pantographs[ end::rear ].valve.start_type == start_t::manual };
Train->mvOccupied->PantSwitchType == "impulse" ? Train->mvOccupied->OperatePantographValve(
end::rear,
( Train->mvOccupied->PantSwitchType == "impulse" ?
operation_t::disable_on : operation_t::disable_on :
operation_t::disable ); operation_t::disable ),
( ismanual ?
range_t::local :
range_t::consist ) );
} }
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
// NOTE: bit of a hax here, we're reusing button reset routine so we don't need a copy in every branch // NOTE: bit of a hax here, we're reusing button reset routine so we don't need a copy in every branch
@@ -6375,7 +6407,8 @@ bool TTrain::Update( double const Deltatime )
ggMainGearStatus.UpdateValue(0.0); ggMainGearStatus.UpdateValue(0.0);
ggMainGearStatus.Update(); ggMainGearStatus.Update();
} }
if (ggIgnitionKey.SubModel) if( ( ggIgnitionKey.SubModel)
&& ( ggIgnitionKey.GetDesiredValue() == 0.0 ) )
{ {
ggIgnitionKey.UpdateValue( ggIgnitionKey.UpdateValue(
( mvControlled->Mains ) ( mvControlled->Mains )
@@ -6383,8 +6416,8 @@ bool TTrain::Update( double const Deltatime )
|| ( fMainRelayTimer > 0.f ) || ( fMainRelayTimer > 0.f )
|| ( ( ggMainButton.SubModel != nullptr ) && ( ggMainButton.GetDesiredValue() > 0.95 ) ) || ( ( ggMainButton.SubModel != nullptr ) && ( ggMainButton.GetDesiredValue() > 0.95 ) )
|| ( ( ggMainOnButton.SubModel != nullptr ) && ( ggMainOnButton.GetDesiredValue() > 0.95 ) ) ); || ( ( ggMainOnButton.SubModel != nullptr ) && ( ggMainOnButton.GetDesiredValue() > 0.95 ) ) );
ggIgnitionKey.Update();
} }
ggIgnitionKey.Update();
} }
if (mvControlled->SlippingWheels) { if (mvControlled->SlippingWheels) {
@@ -6581,8 +6614,10 @@ bool TTrain::Update( double const Deltatime )
btLampkaRadioStop.Turn( mvOccupied->Radio && mvOccupied->RadioStopFlag ); btLampkaRadioStop.Turn( mvOccupied->Radio && mvOccupied->RadioStopFlag );
btLampkaHamulecReczny.Turn(mvOccupied->ManualBrakePos > 0); btLampkaHamulecReczny.Turn(mvOccupied->ManualBrakePos > 0);
// NBMX wrzesien 2003 - drzwi oraz sygnał odjazdu // NBMX wrzesien 2003 - drzwi oraz sygnał odjazdu
if( DynamicObject->Mechanik != nullptr ) {
btLampkaDoorLeft.Turn( DynamicObject->Mechanik->IsAnyDoorOpen[ ( cab_to_end() == end::front ? side::left : side::right ) ] ); btLampkaDoorLeft.Turn( DynamicObject->Mechanik->IsAnyDoorOpen[ ( cab_to_end() == end::front ? side::left : side::right ) ] );
btLampkaDoorRight.Turn( DynamicObject->Mechanik->IsAnyDoorOpen[ ( cab_to_end() == end::front ? side::right : side::left ) ] ); btLampkaDoorRight.Turn( DynamicObject->Mechanik->IsAnyDoorOpen[ ( cab_to_end() == end::front ? side::right : side::left ) ] );
}
btLampkaBlokadaDrzwi.Turn( mvOccupied->Doors.is_locked ); btLampkaBlokadaDrzwi.Turn( mvOccupied->Doors.is_locked );
btLampkaDoorLockOff.Turn( false == mvOccupied->Doors.lock_enabled ); btLampkaDoorLockOff.Turn( false == mvOccupied->Doors.lock_enabled );
btLampkaDepartureSignal.Turn( mvControlled->DepartureSignal ); btLampkaDepartureSignal.Turn( mvControlled->DepartureSignal );

View File

@@ -64,14 +64,29 @@ drivingaid_panel::update() {
} }
// next speed limit // next speed limit
auto const speedlimit { static_cast<int>( std::floor( owner->VelDesired ) ) }; auto const speedlimit { static_cast<int>( std::floor( owner->VelDesired ) ) };
auto const nextspeedlimit { static_cast<int>( std::floor( owner->VelNext ) ) }; auto nextspeedlimit { speedlimit };
auto nextspeedlimitdistance { 0.0 };
if( speedlimit != 0 ) {
// if we aren't allowed to move then any next speed limit is irrelevant
if( ( owner->VelLimitLastDist.first > 0.0 ) && ( owner->VelLimitLastDist.second > 0.0 ) ) {
// first take note of any speed change which should occur after passing potential current speed limit
nextspeedlimit = static_cast<int>( std::floor( owner->VelLimitLastDist.first ) );
nextspeedlimitdistance = owner->VelLimitLastDist.second;
}
auto const speedatproximitydistance{ static_cast<int>( std::floor( owner->VelNext ) ) };
if( ( speedatproximitydistance != speedlimit ) && ( speedatproximitydistance < nextspeedlimit ) ) {
// if there's speed reduction down the road then it's more important than any potential speedup
nextspeedlimit = speedatproximitydistance;
nextspeedlimitdistance = owner->ActualProximityDist;
}
}
std::string nextspeedlimittext; std::string nextspeedlimittext;
if( nextspeedlimit != speedlimit ) { if( nextspeedlimit != speedlimit ) {
std::snprintf( std::snprintf(
m_buffer.data(), m_buffer.size(), m_buffer.data(), m_buffer.size(),
locale::strings[ locale::string::driver_aid_nextlimit ].c_str(), locale::strings[ locale::string::driver_aid_nextlimit ].c_str(),
nextspeedlimit, nextspeedlimit,
driver->ActualProximityDist * 0.001 ); nextspeedlimitdistance * 0.001 );
nextspeedlimittext = m_buffer.data(); nextspeedlimittext = m_buffer.data();
} }
// current speed and limit // current speed and limit