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

Merge branch 'master' into lcd_python.

This commit is contained in:
firleju
2015-11-09 17:56:26 +01:00
9 changed files with 323 additions and 139 deletions

View File

@@ -112,6 +112,7 @@ void TSpeedPos::Clear()
{
iFlags = 0; // brak flag to brak reakcji
fVelNext = -1.0; // prędkość bez ograniczeń
fSectionVelocityDist = 0.0; //brak długości
fDist = 0.0;
vPos = vector3(0, 0, 0);
trTrack = NULL; // brak wskaźnika
@@ -122,47 +123,66 @@ void TSpeedPos::CommandCheck()
TCommandType command = evEvent->Command();
double value1 = evEvent->ValueGet(1);
double value2 = evEvent->ValueGet(2);
if (command == cm_ShuntVelocity)
{ // prędkość manewrową zapisać, najwyżej AI zignoruje przy analizie tabelki
switch (command)
{
case cm_ShuntVelocity:
// prędkość manewrową zapisać, najwyżej AI zignoruje przy analizie tabelki
fVelNext = value1; // powinno być value2, bo druga określa "za"?
iFlags |= 0x200;
}
else if (command == cm_SetVelocity)
{ // w semaforze typu "m" jest ShuntVelocity dla Ms2 i SetVelocity dla S1
iFlags |= spShuntSemaphor;
break;
case cm_SetVelocity:
// w semaforze typu "m" jest ShuntVelocity dla Ms2 i SetVelocity dla S1
// SetVelocity * 0 -> można jechać, ale stanąć przed
// SetVelocity 0 20 -> stanąć przed, potem można jechać 20 (SBL)
// SetVelocity -1 100 -> można jechać, przy następnym ograniczenie (SBL)
// SetVelocity 40 -1 -> PutValues: jechać 40 aż do minięcia (koniec ograniczenia(
fVelNext = value1;
iFlags &= ~0xE00; // nie manewrowa, nie przystanek, nie zatrzymać na SBL
iFlags &= ~(spShuntSemaphor | spPassengerStopPoint | spStopOnSBL);
iFlags |= spSemaphor;// nie manewrowa, nie przystanek, nie zatrzymać na SBL, ale semafor
if (value1 == 0.0) // jeśli pierwsza zerowa
if (value2 != 0.0) // a druga nie
{ // S1 na SBL, można przejechać po zatrzymaniu (tu nie mamy prędkości ani odległości)
fVelNext = value2; // normalnie będzie zezwolenie na jazdę, aby się usunął z tabelki
iFlags |= 0x800; // flaga, że ma zatrzymać; na pewno nie zezwoli na manewry
iFlags |= spStopOnSBL; // flaga, że ma zatrzymać; na pewno nie zezwoli na manewry
}
}
else if (command == cm_PassengerStopPoint) // nie ma dostępu do rozkładu
{ // przystanek, najwyżej AI zignoruje przy analizie tabelki
if ((iFlags & 0x400) == 0)
break;
case cm_SectionVelocity:
// odcinek z ograniczeniem prędkości
fVelNext = value1;
fSectionVelocityDist = value2;
iFlags |= spSectionVel;
break;
case cm_RoadVelocity:
// prędkość drogowa (od tej pory będzie jako domyślna najwyższa)
fVelNext = value1;
iFlags |= spRoadVel;
break;
case cm_PassengerStopPoint:
// nie ma dostępu do rozkładu
// przystanek, najwyżej AI zignoruje przy analizie tabelki
if ((iFlags & spPassengerStopPoint) == 0)
fVelNext = 0.0; // TrainParams->IsStop()?0.0:-1.0; //na razie tak
iFlags |= 0x400; // niestety nie da się w tym miejscu współpracować z rozkładem
}
else if (command == cm_SetProximityVelocity)
{ // ignorować
fVelNext = -1;
}
else if (command == cm_OutsideStation)
{ // w trybie manewrowym: skanować od niej wstecz i stanąć po wyjechaniu za sygnalizator i
iFlags |= spPassengerStopPoint; // niestety nie da się w tym miejscu współpracować z rozkładem
break;
//case cm_SetProximityVelocity:
// // odcinek z ograniczeniem prędkości o podanej długości
// fVelNext = value1;
// iFlags |= spProximityVelocity;
// fSectionVelocityDist = value2;
// break;
case cm_OutsideStation:
// w trybie manewrowym: skanować od niej wstecz i stanąć po wyjechaniu za sygnalizator i
// zmienić kierunek
// w trybie pociągowym: można przyspieszyć do wskazanej prędkości (po zjechaniu z rozjazdów)
fVelNext = -1;
iFlags |= 0x2100; // W5
}
else
{ // inna komenda w evencie skanowanym powoduje zatrzymanie i wysłanie tej komendy
iFlags &= ~0xE00; // nie manewrowa, nie przystanek, nie zatrzymać na SBL
fVelNext = 0; // jak nieznana komenda w komórce sygnałowej, to ma stać
iFlags |= spOutsideStation; // W5
break;
default:
// inna komenda w evencie skanowanym powoduje zatrzymanie i wysłanie tej komendy
iFlags &= ~(spShuntSemaphor | spPassengerStopPoint |
spStopOnSBL); // nie manewrowa, nie przystanek, nie zatrzymać na SBL
fVelNext = -1.0; // jak nieznana komenda w komórce sygnałowej, to pokazujemy w tabelce ale
// ignorujemy
}
};
@@ -180,17 +200,17 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len)
if (iska < 0.0) // iloczyn skalarny jest ujemny, gdy punkt jest z tyłu
{ // jeśli coś jest z tyłu, to dokładna odległość nie ma już większego znaczenia
fDist = -fDist; // potrzebne do badania wyjechania składem poza ograniczenie
if (iFlags & 32) // 32 ustawione, gdy obiekt już został minięty
if (iFlags & spElapsed) // 32 ustawione, gdy obiekt już został minięty
{ // jeśli minięty (musi być minięty również przez końcówkę składu)
}
else
{
iFlags ^= 32; // 32-minięty - będziemy liczyć odległość względem przeciwnego końca
// toru (nadal może być z przodu i ogdaniczać)
iFlags ^= spElapsed; // 32-minięty - będziemy liczyć odległość względem przeciwnego końca
// toru (nadal może być z przodu i ograniczać)
if ((iFlags & 0x43) == 3) // tylko jeśli (istotny) tor, bo eventy są punktowe
if (trTrack) // może być NULL, jeśli koniec toru (????)
vPos =
(iFlags & 4) ?
(iFlags & spReverse) ?
trTrack->CurrentSegment()->FastGetPoint_0() :
trTrack->CurrentSegment()->FastGetPoint_1(); // drugi koniec istotny
}
@@ -201,14 +221,14 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len)
// dokładniejsze wartości
}
if (fDist > 0.0) // nie może być 0.0, a przypadkiem mogło by się trafić i było by źle
if ((iFlags & 32) == 0) // 32 ustawione, gdy obiekt już został minięty
if ((iFlags & spElapsed) == 0) // 32 ustawione, gdy obiekt już został minięty
{ // jeśli obiekt nie został minięty, można od niego zliczać narastająco (inaczej może być
// problem z wektorem kierunku)
len = fDist = len + fDist; // zliczanie dlugości narastająco
*p = vPos; // nowy punkt odniesienia
*dir = Normalize(v); // nowy wektor kierunku od poprzedniego obiektu do aktualnego
}
if (iFlags & 2) // jeśli tor
if (iFlags & spTrack) // jeśli tor
{
if (trTrack) // może być NULL, jeśli koniec toru (???)
{
@@ -221,25 +241,25 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len)
// głównej drogi - chyba że jest równorzędne...
fVelNext = 30.0; // uzależnić prędkość od promienia; albo niech będzie
// ograniczona w skrzyżowaniu (velocity z ujemną wartością)
if ((iFlags & 32) == 0) // jeśli nie wjechał
if ((iFlags & spElapsed) == 0) // jeśli nie wjechał
if (trTrack->iNumDynamics > 0) // a skrzyżowanie zawiera pojazd
fVelNext =
0.0; // to zabronić wjazdu (chyba że ten z przodu też jedzie prosto)
}
if (iFlags & 8) // jeśli odcinek zmienny
if (iFlags & spSwitch) // jeśli odcinek zmienny
{
if (bool(trTrack->GetSwitchState() & 1) !=
bool(iFlags & 16)) // czy stan się zmienił?
bool(iFlags & spSwitchStatus)) // czy stan się zmienił?
{ // Ra: zakładam, że są tylko 2 możliwe stany
iFlags ^= 16;
iFlags ^= spSwitchStatus;
// fVelNext=trTrack->VelocityGet(); //nowa prędkość
if ((iFlags & 32) == 0)
if ((iFlags & spElapsed) == 0)
return true; // jeszcze trzeba skanowanie wykonać od tego toru
// problem jest chyba, jeśli zwrotnica się przełoży zaraz po zjechaniu z niej
// na Mydelniczce potrafi skanować na wprost mimo pojechania na bok
}
// poniższe nie dotyczy trybu łączenia?
if ((iFlags & 32) ? false :
if ((iFlags & spElapsed) ? false :
trTrack->iNumDynamics >
0) // jeśli jeszcze nie wjechano na tor, a coś na nim jest
fDist -= 30.0, fVelNext = 0.0; // to niech stanie w zwiększonej odległości
@@ -248,7 +268,7 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len)
}
}
}
else if (iFlags & 0x100) // jeśli event
else if (iFlags & spEvent) // jeśli event
{ // odczyt komórki pamięci najlepiej by było zrobić jako notyfikację, czyli zmiana komórki
// wywoła jakąś podaną funkcję
CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości
@@ -258,12 +278,12 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len)
AnsiString TSpeedPos::TableText()
{ // pozycja tabelki prędkości
if (iFlags & 0x1)
if (iFlags & spEnabled)
{ // o ile pozycja istotna
if (iFlags & 0x2) // jeśli tor
if (iFlags & spTrack) // jeśli tor
return "Flags=#" + IntToHex(iFlags, 8) + ", Dist=" + FloatToStrF(fDist, ffFixed, 7, 1) +
", Vel=" + AnsiString(fVelNext) + ", Track=" + trTrack->NameGet();
else if (iFlags & 0x100) // jeśli event
else if (iFlags & spEvent) // jeśli event
return "Flags=#" + IntToHex(iFlags, 8) + ", Dist=" + FloatToStrF(fDist, ffFixed, 7, 1) +
", Vel=" + AnsiString(fVelNext) + ", Event=" + evEvent->asName;
}
@@ -273,7 +293,7 @@ AnsiString TSpeedPos::TableText()
bool TSpeedPos::Set(TEvent *e, double d)
{ // zapamiętanie zdarzenia
fDist = d;
iFlags = 0x101; // event+istotny
iFlags = spEnabled | spEvent; // event+istotny
evEvent = e;
vPos = e->PositionGet(); // współrzędne eventu albo komórki pamięci (zrzutować na tor?)
CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości
@@ -287,17 +307,17 @@ void TSpeedPos::Set(TTrack *t, double d, int f)
if (trTrack)
{
iFlags = f | (trTrack->eType == tt_Normal ? 2 : 10); // zapamiętanie kierunku wraz z typem
if (iFlags & 8)
if (iFlags & spSwitch)
if (trTrack->GetSwitchState() & 1)
iFlags |= 16;
iFlags |= spSwitchStatus;
fVelNext = trTrack->VelocityGet();
if (trTrack->iDamageFlag & 128)
fVelNext = 0.0; // jeśli uszkodzony, to też stój
if (iFlags & 64)
if (iFlags & spEnd)
fVelNext = (trTrack->iCategoryFlag & 1) ?
0.0 :
20.0; // jeśli koniec, to pociąg stój, a samochód zwolnij
vPos = (bool(iFlags & 4) != bool(iFlags & 64)) ?
vPos = (bool(iFlags & spReverse) != bool(iFlags & spEnd)) ?
trTrack->CurrentSegment()->FastGetPoint_1() :
trTrack->CurrentSegment()->FastGetPoint_0();
}
@@ -342,11 +362,15 @@ bool TController::TableAddNew()
bool TController::TableNotFound(TEvent *e)
{ // sprawdzenie, czy nie został już dodany do tabelki (np. podwójne W4 robi problemy)
int i, j = (iLast + 1) % iSpeedTableSize; // j, aby sprawdzić też ostatnią pozycję
for (i = iFirst; i != j; i = (i + 1) % iSpeedTableSize)
if ((sSpeedTable[i].iFlags & 0x101) == 0x101) // o ile używana pozycja
if (sSpeedTable[i].evEvent == e)
return false; // już jest, drugi raz dodawać nie ma po co
int j = (iLast + 1) % iSpeedTableSize; // j, aby sprawdzić też ostatnią pozycję
for (int i = iFirst; i != j; i = (i + 1) % iSpeedTableSize)
if ((sSpeedTable[i].iFlags & (spEnabled | spEvent)) == (spEnabled |
spEvent)) // o ile używana pozycja
if (sSpeedTable[i].evEvent == e)
{
WriteLog("TableNotFound: Event already in SpeedTable: " + sSpeedTable[i].evEvent->asName);
return false; // już jest, drugi raz dodawać nie ma po co
}
return true; // nie ma, czyli można dodać
};
@@ -381,7 +405,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
}
else
{ // kontynuacja skanowania od ostatnio sprawdzonego toru (w ostatniej pozycji zawsze jest tor)
if (sSpeedTable[iLast].iFlags & 0x10000) // zatkanie
if (sSpeedTable[iLast].iFlags & spEndOfTable) // zatkanie
{ // jeśli zapełniła się tabelka
if ((iLast + 1) % iSpeedTableSize == iFirst) // jeśli nadal jest zapełniona
return; // nic się nie da zrobić
@@ -391,12 +415,13 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
return; // już lepiej, ale jeszcze nie tym razem
sSpeedTable[iLast].iFlags &= 0xBE; // kontynuować próby doskanowania
}
else if (VelNext == 0)
return; // znaleziono semafor lub tor z prędkością zero i nie ma co dalej sprawdzać
//else if (VelNext == 0)
// return; // znaleziono semafor lub tor z prędkością zero i nie ma co dalej sprawdzać
//trzeba dalej sprawdzać, gdyż przy stopinfo potrafił zgubić semafor
pTrack = sSpeedTable[iLast].trTrack; // ostatnio sprawdzony tor
if (!pTrack)
return; // koniec toru, to nie ma co sprawdzać (nie ma prawa tak być)
fLastDir = sSpeedTable[iLast].iFlags & 4 ?
fLastDir = sSpeedTable[iLast].iFlags & spReverse ?
-1.0 :
1.0; // flaga ustawiona, gdy Point2 toru jest bliżej
fCurrentDistance = sSpeedTable[iLast].fDist; // aktualna odległość do jego Point1
@@ -565,27 +590,40 @@ void TController::TableCheck(double fDistance)
double len = 0.0; // odległość będziemy zliczać narastająco
for (int i = iFirst; i != iLast; i = (i + 1) % iSpeedTableSize)
{ // aktualizacja rekordów z wyjątkiem ostatniego
if (sSpeedTable[i].iFlags & 1) // jeśli pozycja istotna
if (sSpeedTable[i].iFlags & spEnabled) // jeśli pozycja istotna
{
if (sSpeedTable[i].Update(&pos, &dir, len))
{
iLast = i; // wykryta zmiana zwrotnicy - konieczne ponowne przeskanowanie
// dalszej części
break; // nie kontynuujemy pętli, trzeba doskanować ciąg dalszy
int k = (iLast + 1) % iSpeedTableSize; // skanujemy razem z ostatnią pozycją
for (int j = (i+1) % iSpeedTableSize; j != k; j = (j + 1) % iSpeedTableSize)
{ // kasowanie wszystkich rekordów za zmienioną zwrotnicą
//if (sSpeedTable[j].iFlags & spTrack)
// WriteLog("TableCheck: Switch change. Delete from table: " + sSpeedTable[j].trTrack->NameGet());
//else if (sSpeedTable[j].iFlags & spEvent)
// WriteLog("TableCheck: Switch change. Delete from table: " + sSpeedTable[j].evEvent->asName);
sSpeedTable[j].iFlags = 0;
}
TablePurger();
iLast = i; // pokazujemy gdzie jest ostatni kawałek
break; // nie kontynuujemy pętli, trzeba doskanować ciąg dalszy
}
if (sSpeedTable[i].iFlags & 2) // jeśli odcinek
if (sSpeedTable[i].iFlags & spTrack) // jeśli odcinek
{
if (sSpeedTable[i].fDist < -fLength) // a skład wyjechał całą długością poza
{ // degradacja pozycji
sSpeedTable[i].iFlags &= ~1; // nie liczy się
// WriteLog( "TableCheck: Track is behind. Delete from table: " + sSpeedTable[i].trTrack->NameGet());
sSpeedTable[i].iFlags &= ~spEnabled; // nie liczy się
}
else if ((sSpeedTable[i].iFlags & 0xF0000028) ==
0x20) // jest z tyłu (najechany) i nie jest zwrotnicą ani skrzyżowaniem
if (sSpeedTable[i].fVelNext < 0) // a nie ma ograniczenia prędkości
sSpeedTable[i].iFlags =
0; // to nie ma go po co trzymać (odtykacz usunie ze środka)
spElapsed) // jest z tyłu (najechany) i nie jest zwrotnicą ani skrzyżowaniem
if (sSpeedTable[i].fVelNext < 0) // a nie ma ograniczenia prędkości
{
sSpeedTable[i].iFlags =
0; // to nie ma go po co trzymać (odtykacz usunie ze środka)
// WriteLog("TableCheck: Track without speed limit is under train . Delete from table: " + sSpeedTable[i].trTrack->NameGet());
}
}
else if (sSpeedTable[i].iFlags & 0x100) // jeśli event
else if (sSpeedTable[i].iFlags & spEvent) // jeśli event
{
if (sSpeedTable[i].fDist < (sSpeedTable[i].evEvent->Type == tp_PutValues ?
-fLength :
@@ -594,9 +632,10 @@ void TController::TableCheck(double fDistance)
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ą)
sSpeedTable[i].iFlags &= ~1; // degradacja pozycji dla samochodu;
WriteLog("TableCheck: Event is behind. Delete from table: " + sSpeedTable[i].evEvent->asName);
sSpeedTable[i].iFlags &= ~1; // degradacja pozycji dla samochodu;
// semafory usuwane tylko przy sprawdzaniu,
// bo wysyłają komendy
// bo wysyłają komendy
}
}
// if (sSpeedTable[i].fDist<-20.0*fLength) //jeśli to coś jest 20 razy dalej niż
@@ -639,13 +678,13 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
int i, k = iLast - iFirst + 1;
if (k < 0)
k += iSpeedTableSize; // ilość pozycji do przeanalizowania
iDrivigFlags &=
~(moveTrackEnd | moveSwitchFound); // te flagi są ustawiane tutaj, w razie potrzeby
iDrivigFlags &= ~(moveTrackEnd | moveSwitchFound | moveSemaphorFound |
moveSpeedLimitFound); // te flagi są ustawiane tutaj, w razie potrzeby
for (i = iFirst; k > 0; --k, i = (i + 1) % iSpeedTableSize)
{ // sprawdzenie rekordów od (iFirst) do (iLast), o ile są istotne
if (sSpeedTable[i].iFlags & 1) // badanie istotności
if (sSpeedTable[i].iFlags & spEnabled) // badanie istotności
{ // o ile dana pozycja tabelki jest istotna
if (sSpeedTable[i].iFlags & 0x400)
if (sSpeedTable[i].iFlags & spPassengerStopPoint)
{ // jeśli przystanek, trzeba obsłużyć wg rozkładu
if (sSpeedTable[i].evEvent->CommandGet() != asNextStop)
{ // jeśli nazwa nie jest zgodna
@@ -900,26 +939,27 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
} // koniec obsługi W4
v = sSpeedTable[i].fVelNext; // odczyt prędkości do zmiennej pomocniczej
if (sSpeedTable[i].iFlags &
8) // zwrotnice są usuwane z tabelki dopiero po zjechaniu z nich
spSwitch) // zwrotnice są usuwane z tabelki dopiero po zjechaniu z nich
iDrivigFlags |=
moveSwitchFound; // rozjazd z przodu/pod ogranicza np. sens skanowania wstecz
else if (sSpeedTable[i].iFlags & 0x100) // 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ł
if (sSpeedTable[i].iFlags & 0x2000)
//sprawdzanie eventów pasywnych miniętych
if (sSpeedTable[i].iFlags & spOutsideStation)
{ // jeśli W5, to reakcja zależna od trybu jazdy
if (OrderCurrentGet() & Obey_train)
{ // w trybie pociągowym: można przyspieszyć do wskazanej prędkości (po
// zjechaniu z rozjazdów)
v = -1.0; // ignorować?
if (sSpeedTable[i].fDist < 0.0) // jeśli wskaźnik został minięty
//TODO trzeba zmienić przypisywanie VelSignal na VelSignalLast
if (sSpeedTable[i].fDist < 0.0) // jeśli wskaźnik został minięty
{
VelSignal = v; //!!! ustawienie, gdy przejechany jest lepsze niż wcale,
// ale to jeszcze nie to
VelSignalLast = v; //ustawienie prędkości na -1
// iStationStart=TrainParams->StationIndex; //zaktualizować
// wyświetlanie rozkładu
}
else if (!(iDrivigFlags & moveSwitchFound)) // jeśli rozjazdy już minięte
VelSignal = v; //!!! to też koniec ograniczenia
VelSignalLast = v; //!!! to też koniec ograniczenia
}
else
{ // w trybie manewrowym: skanować od niego wstecz, stanąć po wyjechaniu za
@@ -931,7 +971,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// koniec toru)
}
}
else if (sSpeedTable[i].iFlags & 0x800)
else if (sSpeedTable[i].iFlags & spStopOnSBL)
{ // jeśli S1 na SBL
if (mvOccupied->Vel < 2.0) // stanąć nie musi, ale zwolnić przynajmniej
if (sSpeedTable[i].fDist < fMaxProximityDist) // jest w maksymalnym zasięgu
@@ -946,25 +986,83 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// pociągu z przodu!
}
if (eSignSkip != sSpeedTable[i].evEvent) // jeśli ten SBL nie jest do pominięcia
v = sSpeedTable[i].evEvent->ValueGet(1); // to ma 0 odczytywać
// TODO sprawdzić do której zmiennej jest przypisywane v i zmienić to tutaj
v = sSpeedTable[i].evEvent->ValueGet(1); // to ma 0 odczytywać
}
else if (sSpeedTable[i].iFlags & spSemaphor)
{ // to semaphor
if (sSpeedTable[i].fDist < 0)
VelSignalLast = sSpeedTable[i].fVelNext; //minięty daje prędkość obowiązującą
else
iDrivigFlags |= moveSemaphorFound; //jeśli z przodu to dajemy falgę, że jest
}
else if (sSpeedTable[i].iFlags & spRoadVel)
{ // to W6
if (sSpeedTable[i].fDist < 0)
VelRoad = sSpeedTable[i].fVelNext;
}
else if (sSpeedTable[i].iFlags & spSectionVel)
{ // to W27
if (sSpeedTable[i].fDist < 0) // teraz trzeba sprawdzić inne warunki
{
if (sSpeedTable[i].fSectionVelocityDist == 0.0)
{
WriteLog("TableUpdate: Event is behind. SVD = 0: " + sSpeedTable[i].evEvent->asName);
sSpeedTable[i].iFlags = 0; // jeśli punktowy to kasujemy i nie dajemy ograniczenia na stałe
}
else if (sSpeedTable[i].fSectionVelocityDist < 0.0)
{ // ograniczenie obowiązujące do następnego
if (sSpeedTable[i].fVelNext == Global::Min0RSpeed(sSpeedTable[i].fVelNext, VelLimitLast) &&
sSpeedTable[i].fVelNext != VelLimitLast)
{ // jeśli ograniczenie jest mniejsze niż obecne to obowiązuje od zaraz
VelLimitLast = sSpeedTable[i].fVelNext;
}
else if (sSpeedTable[i].fDist < -fLength)
{ // jeśli większe to musi wyjechać za poprzednie
VelLimitLast = sSpeedTable[i].fVelNext;
WriteLog("TableUpdate: Event is behind. SVD < 0: " + sSpeedTable[i].evEvent->asName);
sSpeedTable[i].iFlags = 0; // wyjechaliśmy poza poprzednie, można skasować
}
}
else
{ // jeśli większe to ograniczenie ma swoją długość
if (sSpeedTable[i].fVelNext == Global::Min0RSpeed(sSpeedTable[i].fVelNext, VelLimitLast) &&
sSpeedTable[i].fVelNext != VelLimitLast)
{ // jeśli ograniczenie jest mniejsze niż obecne to obowiązuje od zaraz
VelLimitLast = sSpeedTable[i].fVelNext;
}
else if (sSpeedTable[i].fDist < -fLength && sSpeedTable[i].fVelNext != VelLimitLast)
{ // jeśli większe to musi wyjechać za poprzednie
VelLimitLast = sSpeedTable[i].fVelNext;
}
else if (sSpeedTable[i].fDist < -fLength - sSpeedTable[i].fSectionVelocityDist)
{ //
VelLimitLast = -1.0;
WriteLog("TableUpdate: Event is behind. SVD > 0: " + sSpeedTable[i].evEvent->asName);
sSpeedTable[i].iFlags = 0; // wyjechaliśmy poza poprzednie, można skasować
}
}
}
}
//sprawdzenie eventów pasywnych przed nami
if ((mvOccupied->CategoryFlag & 1) ?
sSpeedTable[i].fDist > pVehicles[0]->fTrackBlock - 20.0 :
false) // jak sygnał jest dalej niż zawalidroga
v = 0.0; // to może być podany dla tamtego: jechać tak, jakby tam stop był
else
{ // zawalidrogi nie ma (albo pojazd jest samochodem), sprawdzić sygnał
if (sSpeedTable[i].iFlags & 0x200) // jeśli Tm - w zasadzie to sprawdzić
if (sSpeedTable[i].iFlags & spShuntSemaphor) // jeśli Tm - w zasadzie to sprawdzić
// komendę!
{ // jeśli podana prędkość manewrowa
if ((OrderCurrentGet() & Obey_train) ? v == 0.0 : false)
{ // jeśli tryb pociągowy a tarcze ma ShuntVelocity 0 0
v = -1; // ignorować, chyba że prędkość stanie się niezerowa
if (sSpeedTable[i].iFlags & 0x20) // a jak przejechana
if (sSpeedTable[i].iFlags & spElapsed) // a jak przejechana
sSpeedTable[i].iFlags = 0; // to można usunąć, bo podstawowy automat
// usuwa tylko niezerowe
}
else if (go <= cm_Ready) // jeśli jeszcze nie ma komendy
else if (go == cm_Unknown) // jeśli jeszcze nie ma komendy
if (v != 0.0) // komenda jest tylko gdy ma jechać, bo stoi na podstawie
// tabelki
{ // jeśli nie było komendy wcześniej - pierwsza się liczy - ustawianie
@@ -985,9 +1083,8 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
}
}
}
else // if (sSpeedTable[i].iFlags&0x100) //jeśli semafor !!! Komendę trzeba
// sprawdzić !!!!
if (go <= cm_Ready) // jeśli nie było komendy wcześniej - pierwsza się liczy
else if (!(sSpeedTable[i].iFlags & spSectionVel)) //jeśli jakiś event pasywny ale nie ograniczenie
if (go == cm_Unknown) // jeśli nie było komendy wcześniej - pierwsza się liczy
// - ustawianie VelSignal
if (v < 0.0 ? true : v >= 1.0) // bo wartość 0.1 służy do hamowania tylko
{
@@ -997,12 +1094,13 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// VelSignal=v; //nie do końca tak, to jest druga prędkość; -1 nie
// wpisywać...
if (VelSignal == 0.0)
VelSignal = v; // aby stojący ruszył
VelSignal = -1.0; // aby stojący ruszył
if (sSpeedTable[i].fDist < 0.0) // jeśli przejechany
{
VelSignal = v; //!!! ustawienie, gdy przejechany jest lepsze niż
if (v != 0 ? VelSignal = -1.0 : VelSignal = 0.0)
; // ustawienie, gdy przejechany jest lepsze niż
// wcale, ale to jeszcze nie to
if (sSpeedTable[i].iFlags & 0x100) // jeśli semafor
if (sSpeedTable[i].iFlags & spEvent) // jeśli event
if ((sSpeedTable[i].evEvent != eSignSkip) ?
true :
(sSpeedTable[i].fVelNext != 0.0)) // ale inny niż ten,
@@ -1012,6 +1110,8 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
iDrivigFlags &= ~moveVisibility; // sygnał zezwalający na
// jazdę wyłącza jazdę na
// widoczność (S1 na SBL)
// usunąć jeśli nie jest ograniczeniem prędkości
sSpeedTable[i].iFlags =
0; // to można usunąć (nie mogą być usuwane w skanowaniu)
}
@@ -1032,13 +1132,16 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
} // jeśli event
if (v >= 0.0)
{ // pozycje z prędkością -1 można spokojnie pomijać
d = sSpeedTable[i].fDist;
if ((sSpeedTable[i].iFlags & 0x20) ?
d = sSpeedTable[i].fDist;
if ((sSpeedTable[i].iFlags & spElapsed) ?
false :
d > 0.0) // sygnał lub ograniczenie z przodu (+32=przejechane)
{ // 2014-02: jeśli stoi, a ma do przejechania kawałek, to niech jedzie
if ((mvOccupied->Vel == 0.0) ?
((sSpeedTable[i].iFlags & 0x501) == 0x501) && (d > fMaxProximityDist) :
((sSpeedTable[i].iFlags &
(spEnabled | spEvent | spPassengerStopPoint)) ==
(spEnabled | spEvent | spPassengerStopPoint)) &&
(d > fMaxProximityDist) :
false)
a = (iDrivigFlags & moveStopCloser) ? fAcc : 0.0; // ma podjechać bliżej -
// czy na pewno w tym
@@ -1052,7 +1155,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
fVelDes = v; // ograniczenie aktualnej prędkości
}
}
else if (sSpeedTable[i].iFlags & 2) // jeśli tor
else if (sSpeedTable[i].iFlags & spTrack) // jeśli tor
{ // tor ogranicza prędkość, dopóki cały skład nie przejedzie,
// d=fLength+d; //zamiana na długość liczoną do przodu
if (v >= 1.0) // EU06 się zawieszało po dojechaniu na koniec toru postojowego
@@ -1067,7 +1170,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
else // event trzyma tylko jeśli VelNext=0, nawet po przejechaniu (nie powinno
// dotyczyć samochodów?)
a = (v == 0.0 ? -1.0 : fAcc); // ruszanie albo hamowanie
if (a < fAcc)
if (a < fAcc && v == Min0R(v, fNext))
{ // 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
@@ -1085,7 +1188,8 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
} // if (v>=0.0)
if (fNext >= 0.0)
{ // jeśli ograniczenie
if ((sSpeedTable[i].iFlags & 0x101) == 0x101) // tylko sygnał przypisujemy
if ((sSpeedTable[i].iFlags & (spEnabled | spEvent)) ==
(spEnabled | spEvent)) // tylko sygnał przypisujemy
if (!eSignNext) // jeśli jeszcze nic nie zapisane tam
eSignNext = sSpeedTable[i].evEvent; // dla informacji
if (fNext == 0.0)
@@ -1093,6 +1197,18 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
}
} // if (sSpeedTable[i].iFlags&1)
} // for
if (VelSignalLast >= 0.0 && !(iDrivigFlags & (moveSemaphorFound | moveSwitchFound)) &&
(OrderCurrentGet() & Obey_train))
VelSignalLast = -1.0; // jeśli mieliśmy ograniczenie z semafora i nie ma przed nami
if (VelSignalLast >= 0.0) //analiza spisanych z tabelki ograniczeń i nadpisanie aktualnego
fVelDes = Min0R(fVelDes, VelSignalLast);
if (VelLimitLast >= 0.0)
fVelDes = Min0R(fVelDes, VelLimitLast);
if (VelRoad >= 0.0)
fVelDes = Min0R(fVelDes, VelRoad);
// nastepnego semafora albo zwrotnicy to uznajemy, że mijamy W5
return go;
};
@@ -1104,14 +1220,14 @@ void TController::TablePurger()
k += iSpeedTableSize; // ilość pozycji do przeanalizowania
for (i = iFirst; k > 0; --k, i = (i + 1) % iSpeedTableSize)
{ // sprawdzenie rekordów od (iFirst) do (iLast), o ile są istotne
if ((sSpeedTable[i].iFlags & 1) ?
if ((sSpeedTable[i].iFlags & spEnabled) ?
(sSpeedTable[i].fVelNext < 0) && ((sSpeedTable[i].iFlags & 0xAB) == 0xA3) :
true)
{ // jeśli jest to minięty (0x20) tor (0x03) do liczenia cięciw (0x80), a nie zwrotnica
// (0x08)
for (; k > 0; --k, i = (i + 1) % iSpeedTableSize)
sSpeedTable[i] = sSpeedTable[(i + 1) % iSpeedTableSize]; // skopiowanie
// WriteLog("Odtykacz usuwa pozycję");
for (; k > 0; --k, i = (i + 1) % iSpeedTableSize)
sSpeedTable[i] = sSpeedTable[(i + 1) % iSpeedTableSize]; // skopiowanie
//WriteLog("Odtykacz usuwa pozycję");
iLast = (iLast - 1 + iSpeedTableSize) % iSpeedTableSize; // cofnięcie z zawinięciem
return;
}
@@ -1158,6 +1274,9 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche,
VelSignal = 0.0; // normalnie na początku ma stać, no chyba że jedzie
VelLimit = -1.0; // brak ograniczenia prędkości
VelNext = 120.0;
VelLimitLast = -1.0; // ostatnie ograniczenie bez ograniczenia
VelSignalLast = -1.0; // ostatni semafor też bez ograniczenia
VelRoad = -1.0; // prędkość drogowa bez ograniczenia
AIControllFlag = AI;
pVehicle = NewControll;
ControllingSet(); // utworzenie połączenia do sterowanego pojazdu
@@ -3193,15 +3312,12 @@ bool TController::UpdateSituation(double dt)
if (fMass > 1000000.0)
fBrakeDist *= 2.0; // korekta dla ciężkich, bo przeżynają - da to coś?
if (mvOccupied->BrakeDelayFlag == bdelay_G)
fBrakeDist =
fBrakeDist +
2 *
mvOccupied
->Vel; // dla nastawienia G koniecznie należy wydłużyć drogę na czas reakcji
fBrakeDist = fBrakeDist + 2 * mvOccupied->Vel; // dla nastawienia G
// koniecznie należy wydłużyć drogę na czas reakcji
// double scanmax=(mvOccupied->Vel>0.0)?3*fDriverDist+fBrakeDist:10.0*fDriverDist;
double scanmax = (mvOccupied->Vel > 5.0) ?
400 + fBrakeDist :
50.0 * fDriverDist; // 1000m dla stojących pociągów; Ra 2015-01: przy
30.0 * fDriverDist; // 1500m dla stojących pociągów; Ra 2015-01: przy
// dłuższej drodze skanowania AI jeździ spokojniej
// 2. Sprawdzić, czy tabelka pokrywa założony odcinek (nie musi, jeśli jest STOP).
// 3. Sprawdzić, czy trajektoria ruchu przechodzi przez zwrotnice - jeśli tak, to sprawdzić,
@@ -3722,7 +3838,7 @@ bool TController::UpdateSituation(double dt)
if (VelNext == 0.0)
break; // ale jak coś z przodu zamyka, to ma stać
if (iDrivigFlags & moveStopCloser)
VelSignal = VelDesired; // niech jedzie, jak W4 puściło - nie, ma czekać na
VelSignal = -1.0; // niech jedzie, jak W4 puściło - nie, ma czekać na
// sygnał z sygnalizatora!
case cm_SetVelocity: // od wersji 357 semafor nie budzi wyłączonej lokomotywy
if (!(OrderList[OrderPos] &
@@ -3903,9 +4019,10 @@ bool TController::UpdateSituation(double dt)
VelDesired = 0.0; // jak ma czekać, to nie ma jazdy
// else if (VelSignal<0)
// VelDesired=fVelMax; //ile fabryka dala (Ra: uwzględione wagony)
else if (VelSignal >= 0) // VelSignal>0 jest ograniczeniem prędkości (z semafora)
else if (VelSignal >= 0) // jeśli skład był zatrzymany na początku i teraz już może jechać
VelDesired = Min0R(VelDesired, VelSignal);
if (mvOccupied->RunningTrack.Velmax >=
if (mvOccupied->RunningTrack.Velmax >=
0) // ograniczenie prędkości z trajektorii ruchu
VelDesired =
Min0R(VelDesired,