mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 16:19:19 +02:00
scan table improvements from refs/remotes/firleju/mover_in_c++
This commit is contained in:
249
Driver.cpp
249
Driver.cpp
@@ -106,10 +106,57 @@ std::string StopReasonTable[] = {
|
|||||||
"Error", // stopError //z powodu błędu w obliczeniu drogi hamowania
|
"Error", // stopError //z powodu błędu w obliczeniu drogi hamowania
|
||||||
};
|
};
|
||||||
|
|
||||||
|
double GetDistanceToEvent(TTrack* track, TEvent* event, double scan_dir, double start_dist, int iter = 0, bool back = false)
|
||||||
|
{
|
||||||
|
std::shared_ptr<TSegment> segment = track->CurrentSegment();
|
||||||
|
vector3 pos_event = event->PositionGet();
|
||||||
|
double len1, len2;
|
||||||
|
double sd = scan_dir;
|
||||||
|
double seg_len = scan_dir > 0 ? 0.0 : 1.0;
|
||||||
|
double dzielnik = 1.0 / segment->GetLength();// rozdzielczosc mniej wiecej 1m
|
||||||
|
int krok = 0; // krok obliczeniowy do sprawdzania czy odwracamy
|
||||||
|
len2 = (pos_event - segment->FastGetPoint(seg_len)).Length();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
len1 = len2;
|
||||||
|
seg_len += scan_dir > 0 ? dzielnik : -dzielnik;
|
||||||
|
len2 = (pos_event - segment->FastGetPoint(seg_len)).Length();
|
||||||
|
krok++;
|
||||||
|
} while ((len1 > len2) && (seg_len >= dzielnik && (seg_len <= (1 - dzielnik))));
|
||||||
|
//trzeba sprawdzić czy seg_len nie osiągnął skrajnych wartości, bo wtedy
|
||||||
|
// trzeba sprawdzić tor obok
|
||||||
|
if (1 == krok)
|
||||||
|
sd = -sd; // jeśli tylko jeden krok tzn, że event przy poprzednim sprawdzaym torze
|
||||||
|
if (((seg_len <= dzielnik) || (seg_len > (1 - dzielnik))) && (iter < 3))
|
||||||
|
{ // przejście na inny tor
|
||||||
|
track = track->Neightbour(int(sd), sd);
|
||||||
|
start_dist += (1 == krok) ? 0 : back ? -segment->GetLength() : segment->GetLength();
|
||||||
|
return GetDistanceToEvent(track, event, sd, start_dist, ++iter, 1 == krok ? true : false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // obliczenie mojego toru
|
||||||
|
seg_len -= scan_dir > 0 ? dzielnik : -dzielnik; //trzeba wrócić do pozycji len1
|
||||||
|
seg_len = scan_dir < 0 ? 1 - seg_len : seg_len;
|
||||||
|
seg_len = back ? 1 - seg_len : seg_len; // odwracamy jeśli idzie do tyłu
|
||||||
|
start_dist -= back ? segment->GetLength() : 0;
|
||||||
|
return start_dist + (segment->GetLength() * seg_len);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
TSpeedPos::TSpeedPos(TTrack *track, double dist, int flag)
|
||||||
|
{
|
||||||
|
Set(track, dist, flag);
|
||||||
|
};
|
||||||
|
|
||||||
|
TSpeedPos::TSpeedPos(TEvent *event, double dist, TOrders order)
|
||||||
|
{
|
||||||
|
Set(event, dist, order);
|
||||||
|
};
|
||||||
|
|
||||||
void TSpeedPos::Clear()
|
void TSpeedPos::Clear()
|
||||||
{
|
{
|
||||||
iFlags = 0; // brak flag to brak reakcji
|
iFlags = 0; // brak flag to brak reakcji
|
||||||
@@ -187,64 +234,10 @@ void TSpeedPos::CommandCheck()
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len )
|
bool TSpeedPos::Update()
|
||||||
{ // przeliczenie odległości od punktu (*p), w kierunku (*dir), zaczynając od pojazdu
|
|
||||||
// dla kolejnych pozycji podawane są współrzędne poprzedniego obiektu w (*p)
|
|
||||||
vector3 v = vPos - *p; // wektor od poprzedniego obiektu (albo pojazdu) do punktu zmiany
|
|
||||||
fDist = v.Length(); // długość wektora to odległość pomiędzy czołem a sygnałem albo początkiem toru
|
|
||||||
if (len == 0.0)
|
|
||||||
{ // jeżeli liczymy względem pojazdu
|
|
||||||
double angle;
|
|
||||||
if( dir ) {
|
|
||||||
angle =
|
|
||||||
glm::dot(
|
|
||||||
glm::normalize( glm::make_vec3( &v.x ) ), // towards target
|
|
||||||
glm::normalize( glm::make_vec3( &dir->x ) ) ); // orientation at scan point
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
angle = fDist;
|
|
||||||
}
|
|
||||||
if (angle < 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 & spElapsed) {
|
|
||||||
// jeśli minięty (musi być minięty również przez końcówkę składu)
|
|
||||||
// NOTE: empty branch, why?
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// minięty - będziemy liczyć odległość względem przeciwnego końca
|
if( fDist < 0.0 )
|
||||||
// toru (nadal może być z przodu i ograniczać)
|
iFlags |= spElapsed; // trzeba zazanaczyć, że minięty
|
||||||
iFlags ^= spElapsed;
|
|
||||||
if ((iFlags & (spEnd | spTrack | spEnabled)) == (spTrack | spEnabled)) {
|
|
||||||
// tylko jeśli (istotny) tor, bo eventy są punktowe
|
|
||||||
if (trTrack) {
|
|
||||||
// może być NULL, jeśli koniec toru (????)
|
|
||||||
vPos =
|
|
||||||
(iFlags & spReverse) ?
|
|
||||||
trTrack->CurrentSegment()->FastGetPoint_1() : // drugi koniec istotny
|
|
||||||
trTrack->CurrentSegment()->FastGetPoint_0();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if( fDist < 50.0 ) {
|
|
||||||
// old sceneries use trick of placing 'helper' semaphores underground, which can lead to vehicles running over them instead of stopping in front of them
|
|
||||||
// to account for it at short distances we redo distance calculation on 2d plane
|
|
||||||
fDist = glm::length( glm::vec3( v.x, 0.0, v.z ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fDist > 0.0) // nie może być 0.0, a przypadkiem mogło by się trafić i było by źle
|
|
||||||
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 & spTrack) // road/track
|
if (iFlags & spTrack) // road/track
|
||||||
{
|
{
|
||||||
if (trTrack) {
|
if (trTrack) {
|
||||||
@@ -307,12 +300,6 @@ std::string TSpeedPos::TableText()
|
|||||||
{ // o ile pozycja istotna
|
{ // o ile pozycja istotna
|
||||||
return "Flags:" + to_hex_str(iFlags, 8) + ", Dist:" + to_string(fDist, 1, 6) +
|
return "Flags:" + to_hex_str(iFlags, 8) + ", Dist:" + to_string(fDist, 1, 6) +
|
||||||
", Vel:" + (fVelNext == -1.0 ? " - " : to_string(static_cast<int>(fVelNext), 0, 3)) + ", Name:" + GetName();
|
", Vel:" + (fVelNext == -1.0 ? " - " : to_string(static_cast<int>(fVelNext), 0, 3)) + ", Name:" + GetName();
|
||||||
//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 & spEvent) // jeśli event
|
|
||||||
// return "Flags=#" + IntToHex(iFlags, 8) + ", Dist=" + FloatToStrF(fDist, ffFixed, 7, 1) +
|
|
||||||
// ", Vel=" + AnsiString(fVelNext) + ", Event=" + evEvent->asName;
|
|
||||||
}
|
}
|
||||||
return "Empty";
|
return "Empty";
|
||||||
}
|
}
|
||||||
@@ -376,11 +363,6 @@ void TSpeedPos::Set(TTrack *track, double dist, int flag)
|
|||||||
fVelNext = (trTrack->iCategoryFlag & 1) ?
|
fVelNext = (trTrack->iCategoryFlag & 1) ?
|
||||||
0.0 :
|
0.0 :
|
||||||
20.0; // jeśli koniec, to pociąg stój, a samochód zwolnij
|
20.0; // jeśli koniec, to pociąg stój, a samochód zwolnij
|
||||||
/*
|
|
||||||
vPos = (((iFlags & spReverse) != 0) != ((iFlags & spEnd) != 0)) ?
|
|
||||||
trTrack->CurrentSegment()->FastGetPoint_1() :
|
|
||||||
trTrack->CurrentSegment()->FastGetPoint_0();
|
|
||||||
*/
|
|
||||||
vPos =
|
vPos =
|
||||||
( iFlags & spReverse ) ?
|
( iFlags & spReverse ) ?
|
||||||
trTrack->CurrentSegment()->FastGetPoint_1() :
|
trTrack->CurrentSegment()->FastGetPoint_1() :
|
||||||
@@ -455,16 +437,21 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
|||||||
pTrack = pVehicle->RaTrackGet(); // odcinek, na którym stoi
|
pTrack = pVehicle->RaTrackGet(); // odcinek, na którym stoi
|
||||||
fTrackLength = pVehicle->RaTranslationGet(); // pozycja na tym torze (odległość od Point1)
|
fTrackLength = pVehicle->RaTranslationGet(); // pozycja na tym torze (odległość od Point1)
|
||||||
fLastDir = pVehicle->DirectionGet() * pVehicle->RaDirectionGet(); // ustalenie kierunku skanowania na torze
|
fLastDir = pVehicle->DirectionGet() * pVehicle->RaDirectionGet(); // ustalenie kierunku skanowania na torze
|
||||||
if( fLastDir > 0.0 ) {
|
double odl_czola_od_wozka = (pVehicle->AxlePositionGet() - pVehicle->RearPosition()).Length();
|
||||||
|
if( fLastDir < 0.0 ) {
|
||||||
// jeśli w kierunku Point2 toru
|
// jeśli w kierunku Point2 toru
|
||||||
fTrackLength = pTrack->Length() - fTrackLength; // przeskanowana zostanie odległość do Point2
|
fTrackLength = pTrack->Length() - fTrackLength; // przeskanowana zostanie odległość do Point2
|
||||||
}
|
}
|
||||||
|
fTrackLength -= odl_czola_od_wozka;
|
||||||
|
fCurrentDistance = -fLength - fTrackLength; // aktualna odległość ma być ujemna gdyż jesteśmy na końcu składu
|
||||||
fLastVel = pTrack->VelocityGet(); // aktualna prędkość
|
fLastVel = pTrack->VelocityGet(); // aktualna prędkość
|
||||||
sSpeedTable.clear();
|
sSpeedTable.clear();
|
||||||
iLast = -1;
|
iLast = -1;
|
||||||
tLast = nullptr; //żaden nie sprawdzony
|
tLast = nullptr; //żaden nie sprawdzony
|
||||||
SemNextIndex = -1;
|
SemNextIndex = -1;
|
||||||
SemNextStopIndex = -1;
|
SemNextStopIndex = -1;
|
||||||
|
fTrackLength = pTrack->Length(); //skasowanie zmian w zmiennej żeby poprawnie liczyło w dalszych krokach
|
||||||
|
MoveDistanceReset(); // AI startuje 1s po zaczęciu jazdy i mógł już coś przejechać
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( iTableDirection == 0 ) { return; }
|
if( iTableDirection == 0 ) { return; }
|
||||||
@@ -494,21 +481,14 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const &lastspeedpoint = sSpeedTable[ iLast ];
|
auto const &lastspeedpoint = sSpeedTable[ iLast ];
|
||||||
pTrack = lastspeedpoint.trTrack;
|
pTrack = lastspeedpoint.trTrack;
|
||||||
assert( pTrack != nullptr );
|
assert( pTrack != nullptr );
|
||||||
// flaga ustawiona, gdy Point2 toru jest blizej
|
// flaga ustawiona, gdy Point2 toru jest blizej
|
||||||
fLastDir = (
|
fLastDir = lastspeedpoint.iFlags & spReverse ? -1.0 : 1.0;
|
||||||
TestFlag( lastspeedpoint.iFlags, spReverse ) ?
|
fCurrentDistance = lastspeedpoint.fDist; // aktualna odleglosc do jego Point1
|
||||||
-1.0 :
|
fTrackLength = pTrack->Length();
|
||||||
1.0 );
|
|
||||||
// aktualna odleglosc do jego Point1
|
|
||||||
fCurrentDistance = lastspeedpoint.fDist;
|
|
||||||
// nie doliczac dlugosci gdy: miniety początek lub jazda do konca toru
|
|
||||||
fTrackLength = (
|
|
||||||
( ( lastspeedpoint.iFlags & ( spElapsed | spEnd ) ) != 0 ) ?
|
|
||||||
0.0 :
|
|
||||||
pTrack->Length() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( iTableDirection == 0 ) {
|
if( iTableDirection == 0 ) {
|
||||||
@@ -516,11 +496,6 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( fCurrentDistance >= fDistance ) {
|
|
||||||
// all done
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (fCurrentDistance < fDistance)
|
while (fCurrentDistance < fDistance)
|
||||||
{
|
{
|
||||||
if (pTrack != tLast) // ostatni zapisany w tabelce nie był jeszcze sprawdzony
|
if (pTrack != tLast) // ostatni zapisany w tabelce nie był jeszcze sprawdzony
|
||||||
@@ -532,15 +507,16 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
|||||||
if( ( pEvent = CheckTrackEvent( fLastDir, pTrack ) ) != nullptr ) // jeśli jest semafor na tym torze
|
if( ( pEvent = CheckTrackEvent( fLastDir, pTrack ) ) != nullptr ) // jeśli jest semafor na tym torze
|
||||||
{ // trzeba sprawdzić tabelkę, bo dodawanie drugi raz tego samego przystanku nie jest korzystne
|
{ // trzeba sprawdzić tabelkę, bo dodawanie drugi raz tego samego przystanku nie jest korzystne
|
||||||
if (TableNotFound(pEvent)) // jeśli nie ma
|
if (TableNotFound(pEvent)) // jeśli nie ma
|
||||||
if( TableAddNew() )
|
|
||||||
{
|
{
|
||||||
|
TableAddNew(); // zawsze jest true
|
||||||
|
|
||||||
if (Global::iWriteLogEnabled & 8) {
|
if (Global::iWriteLogEnabled & 8) {
|
||||||
WriteLog("Speed table for " + OwnerName() + " found new event, " + pEvent->asName);
|
WriteLog("Speed table for " + OwnerName() + " found new event, " + pEvent->asName);
|
||||||
}
|
}
|
||||||
auto &newspeedpoint = sSpeedTable[iLast];
|
auto &newspeedpoint = sSpeedTable[iLast];
|
||||||
if( newspeedpoint.Set( pEvent, fCurrentDistance, OrderCurrentGet() ) ) {
|
if (newspeedpoint.Set(pEvent, GetDistanceToEvent(pTrack, pEvent, fLastDir, fCurrentDistance), OrderCurrentGet())) {
|
||||||
|
|
||||||
fDistance = fCurrentDistance; // jeśli sygnał stop, to nie ma potrzeby dalej skanować
|
fDistance = newspeedpoint.fDist; // jeśli sygnał stop, to nie ma potrzeby dalej skanować
|
||||||
SemNextStopIndex = iLast;
|
SemNextStopIndex = iLast;
|
||||||
if (SemNextIndex == -1) {
|
if (SemNextIndex == -1) {
|
||||||
SemNextIndex = iLast;
|
SemNextIndex = iLast;
|
||||||
@@ -567,10 +543,9 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
|||||||
|
|
||||||
if( ( pTrack->VelocityGet() == 0.0 ) // zatrzymanie
|
if( ( pTrack->VelocityGet() == 0.0 ) // zatrzymanie
|
||||||
|| ( pTrack->iAction ) // jeśli tor ma własności istotne dla skanowania
|
|| ( pTrack->iAction ) // jeśli tor ma własności istotne dla skanowania
|
||||||
|| ( pTrack->VelocityGet() != fLastVel ) ) { // następuje zmiana prędkości
|
|| ( pTrack->VelocityGet() != fLastVel ) ) // następuje zmiana prędkości
|
||||||
// odcinek dodajemy do tabelki, gdy jest istotny dla ruchu
|
{ // odcinek dodajemy do tabelki, gdy jest istotny dla ruchu
|
||||||
if (TableAddNew())
|
TableAddNew();
|
||||||
{ // teraz dodatkowo zapamiętanie wybranego segmentu dla skrzyżowania
|
|
||||||
sSpeedTable[ iLast ].Set(
|
sSpeedTable[ iLast ].Set(
|
||||||
pTrack, fCurrentDistance,
|
pTrack, fCurrentDistance,
|
||||||
( fLastDir < 0 ?
|
( fLastDir < 0 ?
|
||||||
@@ -598,7 +573,6 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if ( ( pTrack->fRadius != 0.0 ) // odległość na łuku lepiej aproksymować cięciwami
|
else if ( ( pTrack->fRadius != 0.0 ) // odległość na łuku lepiej aproksymować cięciwami
|
||||||
|| ( ( tLast != nullptr )
|
|| ( ( tLast != nullptr )
|
||||||
&& ( tLast->fRadius != 0.0 ) )) // koniec łuku też jest istotny
|
&& ( tLast->fRadius != 0.0 ) )) // koniec łuku też jest istotny
|
||||||
@@ -626,10 +600,16 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
|||||||
if (pTrack != nullptr )
|
if (pTrack != nullptr )
|
||||||
{ // jeśli kolejny istnieje
|
{ // jeśli kolejny istnieje
|
||||||
if( tLast != nullptr ) {
|
if( tLast != nullptr ) {
|
||||||
|
|
||||||
|
if( ( tLast->VelocityGet() > 0 )
|
||||||
|
&& ( ( tLast->VelocityGet() < pTrack->VelocityGet() )
|
||||||
|
|| ( pTrack->VelocityGet() < 0 ) ) ) {
|
||||||
|
/*
|
||||||
if( ( pTrack->VelocityGet() < 0 ?
|
if( ( pTrack->VelocityGet() < 0 ?
|
||||||
tLast->VelocityGet() > 0 :
|
tLast->VelocityGet() > 0 :
|
||||||
pTrack->VelocityGet() > tLast->VelocityGet() ) ) {
|
pTrack->VelocityGet() > tLast->VelocityGet() ) ) {
|
||||||
// jeśli kolejny ma większą prędkość niż poprzedni, to zapamiętać poprzedni (do czasu wyjechania)
|
// jeśli kolejny ma większą prędkość niż poprzedni, to zapamiętać poprzedni (do czasu wyjechania)
|
||||||
|
|
||||||
if( ( ( ( iLast != -1 )
|
if( ( ( ( iLast != -1 )
|
||||||
&& ( TestFlag( sSpeedTable[ iLast ].iFlags, spEnabled | spTrack ) ) ) ?
|
&& ( TestFlag( sSpeedTable[ iLast ].iFlags, spEnabled | spTrack ) ) ) ?
|
||||||
( sSpeedTable[ iLast ].trTrack != tLast ) :
|
( sSpeedTable[ iLast ].trTrack != tLast ) :
|
||||||
@@ -646,6 +626,24 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
|||||||
spEnabled | spReverse );
|
spEnabled | spReverse );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
if( ( iLast != -1 )
|
||||||
|
&& ( sSpeedTable[ iLast ].trTrack == tLast ) ) {
|
||||||
|
// if the track is already in the table we only need to mark it as relevant
|
||||||
|
sSpeedTable[ iLast ].iFlags |= spEnabled;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// otherwise add it
|
||||||
|
TableAddNew();
|
||||||
|
sSpeedTable[ iLast ].Set(
|
||||||
|
tLast,
|
||||||
|
fCurrentDistance - fTrackLength, // by now the current distance points to beginning of next track
|
||||||
|
( fLastDir > 0 ?
|
||||||
|
pTrack->iPrevDirection :
|
||||||
|
pTrack->iNextDirection ) ?
|
||||||
|
spEnabled :
|
||||||
|
spEnabled | spReverse );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// zwiększenie skanowanej odległości tylko jeśli istnieje dalszy tor
|
// zwiększenie skanowanej odległości tylko jeśli istnieje dalszy tor
|
||||||
@@ -690,26 +688,33 @@ void TController::TableCheck(double fDistance)
|
|||||||
if( iTableDirection != iDirection ) {
|
if( iTableDirection != iDirection ) {
|
||||||
// jak zmiana kierunku, to skanujemy od końca składu
|
// jak zmiana kierunku, to skanujemy od końca składu
|
||||||
TableTraceRoute( fDistance, pVehicles[ 1 ] );
|
TableTraceRoute( fDistance, pVehicles[ 1 ] );
|
||||||
|
TableSort();
|
||||||
}
|
}
|
||||||
else if (iTableDirection)
|
else if (iTableDirection)
|
||||||
{ // trzeba sprawdzić, czy coś się zmieniło
|
{ // trzeba sprawdzić, czy coś się zmieniło
|
||||||
vector3 dir = pVehicles[0]->VectorFront() * pVehicles[0]->DirectionGet(); // wektor kierunku jazdy
|
for (auto &sp : sSpeedTable)
|
||||||
vector3 pos = pVehicles[0]->HeadPosition(); // zaczynamy od pozycji pojazdu
|
{
|
||||||
double len = 0.0; // odległość będziemy zliczać narastająco
|
sp.UpdateDistance(MoveDistanceGet()); // aktualizacja odległości dla wszystkich pozycji tabeli
|
||||||
|
}
|
||||||
|
MoveDistanceReset(); // kasowanie odległości po aktualizacji tabelki
|
||||||
for( int i = 0; i < iLast; ++i )
|
for( int i = 0; i < iLast; ++i )
|
||||||
{ // aktualizacja rekordów z wyjątkiem ostatniego
|
{ // aktualizacja rekordów z wyjątkiem ostatniego
|
||||||
if (sSpeedTable[i].iFlags & spEnabled) // jeśli pozycja istotna
|
if (sSpeedTable[i].iFlags & spEnabled) // jeśli pozycja istotna
|
||||||
{
|
{
|
||||||
if(sSpeedTable[i].Update( &pos, &dir, len ))
|
if (sSpeedTable[i].Update())
|
||||||
{
|
{
|
||||||
if( Global::iWriteLogEnabled & 8 ) {
|
if( Global::iWriteLogEnabled & 8 ) {
|
||||||
WriteLog( "Speed table for " + OwnerName() + " detected switch change at " + sSpeedTable[ i ].trTrack->NameGet() + " (generating fresh trace)" );
|
WriteLog( "Speed table for " + OwnerName() + " detected switch change at " + sSpeedTable[ i ].trTrack->NameGet() + " (generating fresh trace)" );
|
||||||
}
|
}
|
||||||
// NOTE: dirty trick to perform scan from the beginning
|
// usuwamy wszystko za tym torem
|
||||||
// a workaround for current routines not preserving properly scan distance if started from the middle
|
while (sSpeedTable.back().trTrack != sSpeedTable[i].trTrack)
|
||||||
// and the scan extending far beyond specified limit as result
|
{ // usuwamy wszystko dopóki nie trafimy na tą zwrotnicę
|
||||||
iTableDirection = -iDirection;
|
sSpeedTable.pop_back();
|
||||||
|
--iLast;
|
||||||
|
}
|
||||||
|
tLast = sSpeedTable[ i ].trTrack;
|
||||||
TableTraceRoute( fDistance, pVehicles[ 1 ] );
|
TableTraceRoute( fDistance, pVehicles[ 1 ] );
|
||||||
|
TableSort();
|
||||||
// nie kontynuujemy pętli, trzeba doskanować ciąg dalszy
|
// nie kontynuujemy pętli, trzeba doskanować ciąg dalszy
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -743,10 +748,11 @@ void TController::TableCheck(double fDistance)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sSpeedTable[iLast].Update( &pos, &dir, len ); // aktualizacja ostatniego
|
sSpeedTable[iLast].Update(); // aktualizacja ostatniego
|
||||||
// WriteLog("TableCheck: Upate last track. Dist=" + AnsiString(sSpeedTable[iLast].fDist));
|
// WriteLog("TableCheck: Upate last track. Dist=" + AnsiString(sSpeedTable[iLast].fDist));
|
||||||
if( sSpeedTable[ iLast ].fDist < fDistance ) {
|
if( sSpeedTable[ iLast ].fDist < fDistance ) {
|
||||||
TableTraceRoute( fDistance, pVehicles[ 1 ] ); // doskanowanie dalszego odcinka
|
TableTraceRoute( fDistance, pVehicles[ 1 ] ); // doskanowanie dalszego odcinka
|
||||||
|
TableSort();
|
||||||
}
|
}
|
||||||
// garbage collection
|
// garbage collection
|
||||||
TablePurger();
|
TablePurger();
|
||||||
@@ -777,7 +783,14 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
// first 19 chars of the command is expected to be "PassengerStopPoint:" so we skip them
|
// first 19 chars of the command is expected to be "PassengerStopPoint:" so we skip them
|
||||||
if ( ToLower(sSpeedTable[i].evEvent->CommandGet()).compare( 19, sizeof(asNextStop), ToLower(asNextStop)) != 0 )
|
if ( ToLower(sSpeedTable[i].evEvent->CommandGet()).compare( 19, sizeof(asNextStop), ToLower(asNextStop)) != 0 )
|
||||||
{ // jeśli nazwa nie jest zgodna
|
{ // jeśli nazwa nie jest zgodna
|
||||||
if( sSpeedTable[ i ].fDist < -fLength ) {
|
if (sSpeedTable[i].fDist < 300.0 && sSpeedTable[i].fDist > 0) // tylko jeśli W4 jest blisko, przy dwóch może zaczać szaleć
|
||||||
|
{
|
||||||
|
// porównuje do następnej stacji, więc trzeba przewinąć do poprzedniej
|
||||||
|
// nastepnie ustawić następną na aktualną tak żeby prawidłowo ją obsłużył w następnym kroku
|
||||||
|
TrainParams->RewindTimeTable(sSpeedTable[i].evEvent->CommandGet());
|
||||||
|
asNextStop = TrainParams->NextStop();
|
||||||
|
}
|
||||||
|
else if( sSpeedTable[ i ].fDist < -fLength ) {
|
||||||
// jeśli został przejechany
|
// jeśli został przejechany
|
||||||
sSpeedTable[ i ].iFlags = 0; // to można usunąć (nie mogą być usuwane w skanowaniu)
|
sSpeedTable[ i ].iFlags = 0; // to można usunąć (nie mogą być usuwane w skanowaniu)
|
||||||
}
|
}
|
||||||
@@ -1324,7 +1337,8 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
(OrderCurrentGet() & Obey_train))
|
(OrderCurrentGet() & Obey_train))
|
||||||
VelSignalLast = -1.0; // jeśli mieliśmy ograniczenie z semafora i nie ma przed nami
|
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
|
//analiza spisanych z tabelki ograniczeń i nadpisanie aktualnego
|
||||||
|
if (VelSignalLast >= 0.0)
|
||||||
fVelDes = Min0R(fVelDes, VelSignalLast);
|
fVelDes = Min0R(fVelDes, VelSignalLast);
|
||||||
if (VelLimitLast >= 0.0)
|
if (VelLimitLast >= 0.0)
|
||||||
fVelDes = Min0R(fVelDes, VelLimitLast);
|
fVelDes = Min0R(fVelDes, VelLimitLast);
|
||||||
@@ -1404,6 +1418,29 @@ void TController::TablePurger()
|
|||||||
iLast = sSpeedTable.size() - 1;
|
iLast = sSpeedTable.size() - 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void TController::TableSort()
|
||||||
|
{
|
||||||
|
TSpeedPos sp_temp = TSpeedPos(); // uzywany do przenoszenia
|
||||||
|
for (std::size_t i = 0; i < (iLast - 1) && iLast > 0; ++i)
|
||||||
|
{ // pętla tylko do dwóch pozycji od końca bo ostatniej nie modyfikujemy
|
||||||
|
if (sSpeedTable[i].fDist > sSpeedTable[i + 1].fDist)
|
||||||
|
{ // jesli pozycja wcześniejsza jest dalej to źle
|
||||||
|
sp_temp = sSpeedTable[i + 1];
|
||||||
|
sSpeedTable[i + 1] = sSpeedTable[i]; // zamiana
|
||||||
|
sSpeedTable[i] = sp_temp;
|
||||||
|
// jeszcze sprawdzenie czy pozycja nie była indeksowana dla eventów
|
||||||
|
if (SemNextIndex == i)
|
||||||
|
++SemNextIndex;
|
||||||
|
else if (SemNextIndex == i + 1)
|
||||||
|
--SemNextIndex;
|
||||||
|
if (SemNextStopIndex == i)
|
||||||
|
++SemNextStopIndex;
|
||||||
|
else if (SemNextStopIndex == i + 1)
|
||||||
|
--SemNextStopIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche, bool primary) :// czy ma aktywnie prowadzić?
|
TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche, bool primary) :// czy ma aktywnie prowadzić?
|
||||||
@@ -2376,7 +2413,7 @@ bool TController::IncBrake()
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( mvOccupied->BrakeCtrlPos + 1 == mvOccupied->BrakeCtrlPosNo ) {
|
if( mvOccupied->BrakeCtrlPos + 1 == mvOccupied->BrakeCtrlPosNo ) {
|
||||||
if (AccDesired < -0.75) // hamowanie nagle
|
if (AccDesired < -1.5) // hamowanie nagle
|
||||||
OK = mvOccupied->BrakeLevelAdd(1.0);
|
OK = mvOccupied->BrakeLevelAdd(1.0);
|
||||||
else
|
else
|
||||||
OK = false;
|
OK = false;
|
||||||
@@ -4740,7 +4777,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
|| ( ( AccDesired < fAccGravity - 0.1 ) && ( AbsAccS > AccDesired + fBrake_a1[ 0 ] ) ) ) {
|
|| ( ( AccDesired < fAccGravity - 0.1 ) && ( AbsAccS > AccDesired + fBrake_a1[ 0 ] ) ) ) {
|
||||||
// u góry ustawia się hamowanie na fAccThreshold
|
// u góry ustawia się hamowanie na fAccThreshold
|
||||||
if( ( fBrakeTime < 0.0 )
|
if( ( fBrakeTime < 0.0 )
|
||||||
|| ( AccDesired < fAccGravity - 0.75 )
|
|| ( AccDesired < fAccGravity - 0.5 )
|
||||||
|| ( mvOccupied->BrakeCtrlPos <= 0 ) ) {
|
|| ( mvOccupied->BrakeCtrlPos <= 0 ) ) {
|
||||||
// jeśli upłynął czas reakcji hamulca, chyba że nagłe albo luzował
|
// jeśli upłynął czas reakcji hamulca, chyba że nagłe albo luzował
|
||||||
if( true == IncBrake() ) {
|
if( true == IncBrake() ) {
|
||||||
|
|||||||
24
Driver.h
24
Driver.h
@@ -143,8 +143,16 @@ class TSpeedPos
|
|||||||
void CommandCheck();
|
void CommandCheck();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
TSpeedPos(TTrack *track, double dist, int flag);
|
||||||
|
TSpeedPos(TEvent *event, double dist, TOrders order);
|
||||||
|
TSpeedPos() = default;
|
||||||
void Clear();
|
void Clear();
|
||||||
bool Update(vector3 *p, vector3 *dir, double &len );
|
bool Update();
|
||||||
|
// aktualizuje odległość we wpisie
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
UpdateDistance( double dist ) {
|
||||||
|
fDist -= dist; }
|
||||||
bool Set(TEvent *e, double d, TOrders order = Wait_for_orders);
|
bool Set(TEvent *e, double d, TOrders order = Wait_for_orders);
|
||||||
void Set(TTrack *t, double d, int f);
|
void Set(TTrack *t, double d, int f);
|
||||||
std::string TableText();
|
std::string TableText();
|
||||||
@@ -174,6 +182,7 @@ class TController
|
|||||||
TEvent *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu
|
TEvent *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu
|
||||||
std::size_t SemNextIndex{ std::size_t(-1) };
|
std::size_t SemNextIndex{ std::size_t(-1) };
|
||||||
std::size_t SemNextStopIndex{ std::size_t( -1 ) };
|
std::size_t SemNextStopIndex{ std::size_t( -1 ) };
|
||||||
|
double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki
|
||||||
private: // parametry aktualnego składu
|
private: // parametry aktualnego składu
|
||||||
double fLength = 0.0; // długość składu (do wyciągania z ograniczeń)
|
double fLength = 0.0; // długość składu (do wyciągania z ograniczeń)
|
||||||
double fMass = 0.0; // całkowita masa do liczenia stycznej składowej grawitacji
|
double fMass = 0.0; // całkowita masa do liczenia stycznej składowej grawitacji
|
||||||
@@ -372,7 +381,20 @@ class TController
|
|||||||
float
|
float
|
||||||
braking_distance_multiplier( float const Targetvelocity );
|
braking_distance_multiplier( float const Targetvelocity );
|
||||||
void TablePurger();
|
void TablePurger();
|
||||||
|
void TableSort();
|
||||||
|
inline double MoveDistanceGet()
|
||||||
|
{
|
||||||
|
return dMoveLen;
|
||||||
|
}
|
||||||
|
inline void MoveDistanceReset()
|
||||||
|
{
|
||||||
|
dMoveLen = 0.0;
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
|
inline void MoveDistanceAdd(double distance)
|
||||||
|
{
|
||||||
|
dMoveLen += distance * iDirection; //jak jedzie do tyłu to trzeba uwzględniać, że distance jest ujemna
|
||||||
|
}
|
||||||
std::size_t TableSize() const { return sSpeedTable.size(); }
|
std::size_t TableSize() const { return sSpeedTable.size(); }
|
||||||
void TableClear();
|
void TableClear();
|
||||||
int TableDirection() { return iTableDirection; }
|
int TableDirection() { return iTableDirection; }
|
||||||
|
|||||||
@@ -2939,6 +2939,8 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
MoverParameters->AccN *= -ABuGetDirection();
|
MoverParameters->AccN *= -ABuGetDirection();
|
||||||
*/
|
*/
|
||||||
// if (dDOMoveLen!=0.0) //Ra: nie może być, bo blokuje Event0
|
// if (dDOMoveLen!=0.0) //Ra: nie może być, bo blokuje Event0
|
||||||
|
if( Mechanik )
|
||||||
|
Mechanik->MoveDistanceAdd( dDOMoveLen ); // dodanie aktualnego przemieszczenia
|
||||||
Move(dDOMoveLen);
|
Move(dDOMoveLen);
|
||||||
if (!bEnabled) // usuwane pojazdy nie mają toru
|
if (!bEnabled) // usuwane pojazdy nie mają toru
|
||||||
{ // pojazd do usunięcia
|
{ // pojazd do usunięcia
|
||||||
|
|||||||
27
mtable.cpp
27
mtable.cpp
@@ -104,6 +104,33 @@ bool TTrainParameters::UpdateMTable(double hh, double mm, std::string const &New
|
|||||||
return OK; /*czy jest nastepna stacja*/
|
return OK; /*czy jest nastepna stacja*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mtable::TTrainParameters::RewindTimeTable(std::string actualStationName)
|
||||||
|
{
|
||||||
|
//actualStationName = ToLower(actualStationName); // na małe znaki
|
||||||
|
if (int s = actualStationName.find("PassengerStopPoint:") != std::string::npos)
|
||||||
|
{
|
||||||
|
actualStationName = ToLower(actualStationName.substr(s + 19));
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= StationCount; i++)
|
||||||
|
{ // przechodzimy po całej tabelce i sprawdzamy nazwy stacji (bez pierwszej)
|
||||||
|
if (ToLower(TimeTable[i].StationName) == actualStationName)
|
||||||
|
{ // nazwa stacji zgodna
|
||||||
|
// więc ustawiamy na poprzednią, żeby w następnym kroku poprawnie obsłużyć
|
||||||
|
StationIndex = i - 1;
|
||||||
|
if (StationIndex <
|
||||||
|
StationCount) // Ra: "<", bo dodaje 1 przy przejściu do następnej stacji
|
||||||
|
{ // jeśli nie ostatnia stacja
|
||||||
|
NextStationName = TimeTable[StationIndex + 1].StationName; // zapamiętanie nazwy
|
||||||
|
TTVmax = TimeTable[StationIndex + 1]
|
||||||
|
.vmax; // Ra: nowa prędkość rozkładowa na kolejnym odcinku
|
||||||
|
}
|
||||||
|
else // gdy ostatnia stacja
|
||||||
|
NextStationName = ""; // nie ma następnej stacji
|
||||||
|
break; // znaleźliśmy więc kończymy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TTrainParameters::StationIndexInc()
|
void TTrainParameters::StationIndexInc()
|
||||||
{ // przejście do następnej pozycji StationIndex<=StationCount
|
{ // przejście do następnej pozycji StationIndex<=StationCount
|
||||||
++StationIndex;
|
++StationIndex;
|
||||||
|
|||||||
1
mtable.h
1
mtable.h
@@ -76,6 +76,7 @@ class TTrainParameters
|
|||||||
bool IsTimeToGo(double hh, double mm);
|
bool IsTimeToGo(double hh, double mm);
|
||||||
bool UpdateMTable(double hh, double mm, std::string const &NewName);
|
bool UpdateMTable(double hh, double mm, std::string const &NewName);
|
||||||
bool UpdateMTable( simulation_time const &Time, std::string const &NewName );
|
bool UpdateMTable( simulation_time const &Time, std::string const &NewName );
|
||||||
|
void RewindTimeTable( std::string actualStationName );
|
||||||
TTrainParameters( std::string const &NewTrainName );
|
TTrainParameters( std::string const &NewTrainName );
|
||||||
void NewName(std::string const &NewTrainName);
|
void NewName(std::string const &NewTrainName);
|
||||||
void UpdateVelocity(int StationCount, double vActual);
|
void UpdateVelocity(int StationCount, double vActual);
|
||||||
|
|||||||
Reference in New Issue
Block a user