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

build 170531. fix for pantograph pressure switch activation, partial fix for event sorting

This commit is contained in:
tmj-fstate
2017-06-01 16:21:17 +02:00
parent d2a9f7080e
commit a28b3d5af9
6 changed files with 113 additions and 54 deletions

View File

@@ -469,6 +469,16 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
} }
else { else {
if( iTableDirection == 0 ) { return; } if( iTableDirection == 0 ) { return; }
// NOTE: provisory fix for BUG: sempahor indices no longer matching table size
// TODO: find and really fix the reason it happens
if( ( SemNextIndex != -1 )
&& ( SemNextIndex >= sSpeedTable.size() ) ) {
SemNextIndex = -1;
}
if( ( SemNextStopIndex != -1 )
&& ( SemNextStopIndex >= sSpeedTable.size() ) ) {
SemNextStopIndex = -1;
}
// kontynuacja skanowania od ostatnio sprawdzonego toru (w ostatniej pozycji zawsze jest tor) // kontynuacja skanowania od ostatnio sprawdzonego toru (w ostatniej pozycji zawsze jest tor)
if( ( SemNextStopIndex != -1 ) if( ( SemNextStopIndex != -1 )
&& ( sSpeedTable[SemNextStopIndex].fVelNext < 1.0 ) ) { && ( sSpeedTable[SemNextStopIndex].fVelNext < 1.0 ) ) {
@@ -1335,7 +1345,6 @@ void TController::TablePurger()
// we can only update pointers safely after new table is finalized, so record their indices until then // we can only update pointers safely after new table is finalized, so record their indices until then
for( std::size_t idx = 0; idx < sSpeedTable.size() - 1; ++idx ) { for( std::size_t idx = 0; idx < sSpeedTable.size() - 1; ++idx ) {
// cache placement of semaphors in the new table, if we encounter them // cache placement of semaphors in the new table, if we encounter them
// NOTE: we rely on the semaphor actually getting added in the next step rather than skipped, but it's a pretty safe bet
if( idx == SemNextIndex ) { if( idx == SemNextIndex ) {
SemNextIndex = trimmedtable.size(); SemNextIndex = trimmedtable.size();
} }
@@ -1346,6 +1355,13 @@ void TController::TablePurger()
if( ( 0 == ( speedpoint.iFlags & spEnabled ) ) if( ( 0 == ( speedpoint.iFlags & spEnabled ) )
|| ( ( speedpoint.iFlags & ( spElapsed | spTrack | spCurve | spSwitch ) == ( spElapsed | spTrack | spCurve ) ) || ( ( speedpoint.iFlags & ( spElapsed | spTrack | spCurve | spSwitch ) == ( spElapsed | spTrack | spCurve ) )
&& ( speedpoint.fVelNext < 0.0 ) ) ) { && ( speedpoint.fVelNext < 0.0 ) ) ) {
// if the trimmed point happens to be currently active semaphor we need to invalidate their placements
if( idx == SemNextIndex ) {
SemNextIndex = -1;
}
if( idx == SemNextStopIndex ) {
SemNextStopIndex = -1;
}
continue; continue;
} }
// we're left with useful speed point record we should copy // we're left with useful speed point record we should copy
@@ -3365,8 +3381,8 @@ bool TController::UpdateSituation(double dt)
} }
ElapsedTime += dt; ElapsedTime += dt;
WaitingTime += dt; WaitingTime += dt;
fBrakeTime -= // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
dt; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca fBrakeTime -= dt;
fStopTime += dt; // zliczanie czasu postoju, nie ruszy dopóki ujemne fStopTime += dt; // zliczanie czasu postoju, nie ruszy dopóki ujemne
fActionTime += dt; // czas używany przy regulacji prędkości i zamykaniu drzwi fActionTime += dt; // czas używany przy regulacji prędkości i zamykaniu drzwi
if (WriteLogFlag) if (WriteLogFlag)
@@ -3384,7 +3400,7 @@ bool TController::UpdateSituation(double dt)
LastUpdatedTime = LastUpdatedTime + dt; LastUpdatedTime = LastUpdatedTime + dt;
} }
// Ra: skanowanie również dla prowadzonego ręcznie, aby podpowiedzieć prędkość // Ra: skanowanie również dla prowadzonego ręcznie, aby podpowiedzieć prędkość
if ((LastReactionTime > Min0R(ReactionTime, 2.0))) if ((LastReactionTime > std::min(ReactionTime, 2.0)))
{ {
// Ra: nie wiem czemu ReactionTime potrafi dostać 12 sekund, to jest przegięcie, bo przeżyna // Ra: nie wiem czemu ReactionTime potrafi dostać 12 sekund, to jest przegięcie, bo przeżyna
// STÓJ // STÓJ
@@ -3429,18 +3445,48 @@ bool TController::UpdateSituation(double dt)
if (AIControllFlag) if (AIControllFlag)
{ // tu bedzie logika sterowania { // tu bedzie logika sterowania
if (mvOccupied->CommandIn.Command != "") if (mvOccupied->CommandIn.Command != "")
if (!mvOccupied->RunInternalCommand()) // rozpoznaj komende bo lokomotywa jej nie if( !mvOccupied->RunInternalCommand() ) {
// rozpoznaje // rozpoznaj komende bo lokomotywa jej nie rozpoznaje
RecognizeCommand(); // samo czyta komendę wstawioną do pojazdu? RecognizeCommand(); // samo czyta komendę wstawioną do pojazdu?
if (mvOccupied->SecuritySystem.Status > 1) // jak zadziałało CA/SHP }
if (!mvOccupied->SecuritySystemReset()) // to skasuj if( mvOccupied->SecuritySystem.Status > 1 ) {
// if // jak zadziałało CA/SHP
// ((TestFlag(mvOccupied->SecuritySystem.Status,s_ebrake))&&(mvOccupied->BrakeCtrlPos==0)&&(AccDesired>0.0)) if( !mvOccupied->SecuritySystemReset() ) { // to skasuj
if ((TestFlag(mvOccupied->SecuritySystem.Status, s_SHPebrake) || if( ( mvOccupied->BrakeCtrlPos == 0 )
TestFlag(mvOccupied->SecuritySystem.Status, s_CAebrake)) && && ( AccDesired > 0.0 )
(mvOccupied->BrakeCtrlPos == 0) && (AccDesired > 0.0)) && ( ( TestFlag( mvOccupied->SecuritySystem.Status, s_SHPebrake ) )
mvOccupied->BrakeLevelSet( || ( TestFlag( mvOccupied->SecuritySystem.Status, s_CAebrake ) ) ) ) {
0); //!!! hm, może po prostu normalnie sterować hamulcem? //!!! hm, może po prostu normalnie sterować hamulcem?
mvOccupied->BrakeLevelSet( 0 );
}
}
}
// basic emergency stop handling, while at it
if( ( true == mvOccupied->EmergencyBrakeFlag ) // radio-stop
&& ( mvOccupied->Vel < 0.01 ) // and actual stop
&& ( true == mvOccupied->Radio ) ) { // and we didn't touch the radio yet
// turning off the radio should reset the flag, during security system check
if( m_radiocontroltime > 2.5 ) {
// arbitrary 2.5 sec delay between stop and disabling the radio
mvOccupied->Radio = false;
m_radiocontroltime = 0.0;
}
else {
m_radiocontroltime += LastReactionTime;
}
}
if( ( false == mvOccupied->Radio )
&& ( false == mvOccupied->EmergencyBrakeFlag ) ) {
// otherwise if it's safe to do so, turn the radio back on
if( m_radiocontroltime > 5.0 ) {
// arbitrary 5 sec delay before switching radio back on
mvOccupied->Radio = true;
m_radiocontroltime = 0.0;
}
else {
m_radiocontroltime += LastReactionTime;
}
}
} }
switch (OrderList[OrderPos]) switch (OrderList[OrderPos])
{ // ustalenie prędkości przy doczepianiu i odczepianiu, dystansów w pozostałych przypadkach { // ustalenie prędkości przy doczepianiu i odczepianiu, dystansów w pozostałych przypadkach

View File

@@ -201,8 +201,7 @@ class TController
public: public:
double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku
double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI
double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
// hamulca
private: private:
double fReady = 0.0; // poziom odhamowania wagonów double fReady = 0.0; // poziom odhamowania wagonów
bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow
@@ -211,6 +210,7 @@ class TController
double deltalog = 0.05; // przyrost czasu double deltalog = 0.05; // przyrost czasu
double LastReactionTime = 0.0; double LastReactionTime = 0.0;
double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi
double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations
TAction eAction = actSleep; // aktualny stan TAction eAction = actSleep; // aktualny stan
bool HelpMeFlag = false; // wystawiane True jesli cos niedobrego sie dzieje bool HelpMeFlag = false; // wystawiane True jesli cos niedobrego sie dzieje
public: public:

View File

@@ -2472,10 +2472,15 @@ bool TDynamicObject::Update(double dt, double dt1)
} }
else { else {
if( MoverParameters->PantPress >= 4.6 ) { if( MoverParameters->PantPress >= 4.6 ) {
// prime the pressure switch // NOTE: we require active low power source to prime the pressure switch
MoverParameters->PantPressSwitchActive = true; // this is a work-around for potential isssues caused by the switch activating on otherwise idle vehicles, but should check whether it's accurate
// turn off the subsystems lock if( ( true == MoverParameters->Battery )
MoverParameters->PantPressLockActive = false; || ( true == MoverParameters->ConverterFlag ) ) {
// prime the pressure switch
MoverParameters->PantPressSwitchActive = true;
// turn off the subsystems lock
MoverParameters->PantPressLockActive = false;
}
if( MoverParameters->PantPress >= 4.8 ) { if( MoverParameters->PantPress >= 4.8 ) {
// Winger - automatyczne wylaczanie malej sprezarki // Winger - automatyczne wylaczanie malej sprezarki
@@ -5233,22 +5238,27 @@ TDynamicObject * TDynamicObject::ControlledFind()
// jeździć dobrze // jeździć dobrze
// również hamowanie wykonuje się zaworem w członie, a nie w silnikowym... // również hamowanie wykonuje się zaworem w członie, a nie w silnikowym...
TDynamicObject *d = this; // zaczynamy od aktualnego TDynamicObject *d = this; // zaczynamy od aktualnego
if (d->MoverParameters->TrainType & dt_EZT) // na razie dotyczy to EZT if( d->MoverParameters->TrainType & dt_EZT ) {
if (d->NextConnected ? d->MoverParameters->Couplers[1].AllowedFlag & ctrain_depot : false) // na razie dotyczy to EZT
{ // gdy jest człon od sprzęgu 1, a sprzęg łączony if( ( d->NextConnected != nullptr )
// warsztatowo (powiedzmy) && ( true == TestFlag( d->MoverParameters->Couplers[ 1 ].AllowedFlag, coupling::permanent ) ) ) {
if ((d->MoverParameters->Power < 1.0) && (d->NextConnected->MoverParameters->Power > // gdy jest człon od sprzęgu 1, a sprzęg łączony warsztatowo (powiedzmy)
1.0)) // my nie mamy mocy, ale ten drugi ma if( ( d->MoverParameters->Power < 1.0 )
&& ( d->NextConnected->MoverParameters->Power > 1.0 ) ) {
// my nie mamy mocy, ale ten drugi ma
d = d->NextConnected; // będziemy sterować tym z mocą d = d->NextConnected; // będziemy sterować tym z mocą
}
} }
else if (d->PrevConnected ? d->MoverParameters->Couplers[0].AllowedFlag & ctrain_depot : else if( ( d->PrevConnected != nullptr )
false) && ( true == TestFlag( d->MoverParameters->Couplers[ 0 ].AllowedFlag, coupling::permanent ) ) ) {
{ // gdy jest człon od sprzęgu 0, a sprzęg łączony // gdy jest człon od sprzęgu 0, a sprzęg łączony warsztatowo (powiedzmy)
// warsztatowo (powiedzmy) if( ( d->MoverParameters->Power < 1.0 )
if ((d->MoverParameters->Power < 1.0) && (d->PrevConnected->MoverParameters->Power > && ( d->PrevConnected->MoverParameters->Power > 1.0 ) ) {
1.0)) // my nie mamy mocy, ale ten drugi ma // my nie mamy mocy, ale ten drugi ma
d = d->PrevConnected; // będziemy sterować tym z mocą d = d->PrevConnected; // będziemy sterować tym z mocą
}
} }
}
return d; return d;
}; };
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -612,8 +612,10 @@ void TEvent::Load(cParser *parser, vector3 *org)
void TEvent::AddToQuery(TEvent *e) void TEvent::AddToQuery(TEvent *e)
{ // dodanie eventu do kolejki { // dodanie eventu do kolejki
if (evNext ? (e->fStartTime >= evNext->fStartTime) : false) if( ( evNext != nullptr )
evNext->AddToQuery(e); // sortowanie wg czasu && ( e->fStartTime > evNext->fStartTime ) ) {
evNext->AddToQuery( e ); // sortowanie wg czasu
}
else else
{ // dodanie z przodu { // dodanie z przodu
e->evNext = evNext; e->evNext = evNext;

View File

@@ -3178,9 +3178,9 @@ bool TGround::AddToQuery(TEvent *Event, TDynamicObject *Node)
if (!Event->iQueued) // jeśli nie dodany jeszcze do kolejki if (!Event->iQueued) // jeśli nie dodany jeszcze do kolejki
{ // kolejka eventów jest posortowana względem (fStartTime) { // kolejka eventów jest posortowana względem (fStartTime)
Event->Activator = Node; Event->Activator = Node;
if (Event->Type == tp_AddValues ? (Event->fDelay == 0.0) : false) if( ( Event->Type == tp_AddValues )
{ // eventy AddValues trzeba wykonywać natychmiastowo, inaczej kolejka może zgubić && ( Event->fDelay == 0.0 ) ) {
// jakieś dodawanie // eventy AddValues trzeba wykonywać natychmiastowo, inaczej kolejka może zgubić jakieś dodawanie
// Ra: kopiowanie wykonania tu jest bez sensu, lepiej by było wydzielić funkcję // Ra: kopiowanie wykonania tu jest bez sensu, lepiej by było wydzielić funkcję
// wykonującą eventy i ją wywołać // wykonującą eventy i ją wywołać
if (EventConditon(Event)) if (EventConditon(Event))
@@ -3208,11 +3208,10 @@ bool TGround::AddToQuery(TEvent *Event, TDynamicObject *Node)
std::to_string(Event->Params[1].asdouble) + " " + std::to_string(Event->Params[1].asdouble) + " " +
std::to_string(Event->Params[2].asdouble)); std::to_string(Event->Params[2].asdouble));
} }
Event = // jeśli jest kolejny o takiej samej nazwie, to idzie do kolejki (and if there's no joint event it'll be set to null and processing will end here)
Event Event = Event->evJoined;
->evJoined; // jeśli jest kolejny o takiej samej nazwie, to idzie do kolejki
} }
if (Event) if( Event != nullptr )
{ // standardowe dodanie do kolejki { // standardowe dodanie do kolejki
WriteLog("EVENT ADDED TO QUEUE: " + Event->asName + (Node ? (" by " + Node->asName) : "")); WriteLog("EVENT ADDED TO QUEUE: " + Event->asName + (Node ? (" by " + Node->asName) : ""));
Event->fStartTime = Event->fStartTime =
@@ -3221,10 +3220,13 @@ bool TGround::AddToQuery(TEvent *Event, TDynamicObject *Node)
Event->fStartTime += Event->fRandomDelay * Random(10000) * Event->fStartTime += Event->fRandomDelay * Random(10000) *
0.0001; // doliczenie losowego czasu opóźnienia 0.0001; // doliczenie losowego czasu opóźnienia
++Event->iQueued; // zabezpieczenie przed podwójnym dodaniem do kolejki ++Event->iQueued; // zabezpieczenie przed podwójnym dodaniem do kolejki
if (QueryRootEvent ? Event->fStartTime >= QueryRootEvent->fStartTime : false) if( ( QueryRootEvent != nullptr )
QueryRootEvent->AddToQuery(Event); // dodanie gdzieś w środku && ( Event->fStartTime > QueryRootEvent->fStartTime ) ) {
else // dodanie gdzieś w środku
{ // dodanie z przodu: albo nic nie ma, albo ma być wykonany szybciej niż pierwszy QueryRootEvent->AddToQuery( Event );
}
else {
// dodanie z przodu: albo nic nie ma, albo ma być wykonany szybciej niż pierwszy
Event->evNext = QueryRootEvent; Event->evNext = QueryRootEvent;
QueryRootEvent = Event; QueryRootEvent = Event;
} }
@@ -3355,11 +3357,9 @@ bool TGround::CheckQuery()
{ // to teraz on będzie następny do wykonania { // to teraz on będzie następny do wykonania
QueryRootEvent = QueryRootEvent->evJoined; // następny będzie ten doczepiony QueryRootEvent = QueryRootEvent->evJoined; // następny będzie ten doczepiony
QueryRootEvent->evNext = tmpEvent->evNext; // pamiętając o następnym z kolejki QueryRootEvent->evNext = tmpEvent->evNext; // pamiętając o następnym z kolejki
QueryRootEvent->fStartTime = QueryRootEvent->fStartTime = tmpEvent->fStartTime; // czas musi być ten sam, bo nie jest aktualizowany
tmpEvent->fStartTime; // czas musi być ten sam, bo nie jest aktualizowany
QueryRootEvent->Activator = tmpEvent->Activator; // pojazd aktywujący QueryRootEvent->Activator = tmpEvent->Activator; // pojazd aktywujący
// w sumie można by go dodać normalnie do kolejki, ale trzeba te połączone posortować wg // w sumie można by go dodać normalnie do kolejki, ale trzeba te połączone posortować wg czasu wykonania
// czasu wykonania
} }
else // a jak nazwa jest unikalna, to kolejka idzie dalej else // a jak nazwa jest unikalna, to kolejka idzie dalej
QueryRootEvent = QueryRootEvent->evNext; // NULL w skrajnym przypadku QueryRootEvent = QueryRootEvent->evNext; // NULL w skrajnym przypadku
@@ -3880,9 +3880,10 @@ bool TGround::GetTraction(TDynamicObject *model)
node->hvTraction node->hvTraction
->vParametric; // współczynniki równania parametrycznego ->vParametric; // współczynniki równania parametrycznego
fRaParam = -DotProduct(pant0, vFront); fRaParam = -DotProduct(pant0, vFront);
fRaParam = -(DotProduct(node->hvTraction->pPoint1, vFront) + auto const paramfrontdot = DotProduct( vParam, vFront );
fRaParam) / fRaParam =
DotProduct(vParam, vFront); -( DotProduct( node->hvTraction->pPoint1, vFront ) + fRaParam )
/ ( paramfrontdot != 0.0 ? paramfrontdot : 0.001 ); // div0 trap
if ((fRaParam >= -0.001) ? (fRaParam <= 1.001) : false) if ((fRaParam >= -0.001) ? (fRaParam <= 1.001) : false)
{ // jeśli tylko jest w przedziale, wyznaczyć odległość wzdłuż { // jeśli tylko jest w przedziale, wyznaczyć odległość wzdłuż
// wektorów vUp i vLeft // wektorów vUp i vLeft

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 17 #define VERSION_MAJOR 17
#define VERSION_MINOR 525 #define VERSION_MINOR 531
#define VERSION_REVISION 0 #define VERSION_REVISION 0