mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
5484 lines
295 KiB
C++
5484 lines
295 KiB
C++
/*
|
||
This Source Code Form is subject to the
|
||
terms of the Mozilla Public License, v.
|
||
2.0. If a copy of the MPL was not
|
||
distributed with this file, You can
|
||
obtain one at
|
||
http://mozilla.org/MPL/2.0/.
|
||
*/
|
||
/*
|
||
MaSzyna EU07 locomotive simulator
|
||
Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
||
|
||
*/
|
||
|
||
#include "system.hpp"
|
||
#include "classes.hpp"
|
||
#pragma hdrstop
|
||
|
||
#include "Driver.h"
|
||
#include "mtable.h"
|
||
#include "DynObj.h"
|
||
#include <math.h>
|
||
#include "Globals.h"
|
||
#include "Event.h"
|
||
#include "Ground.h"
|
||
#include "MemCell.h"
|
||
#include "World.h"
|
||
#include "dir.h"
|
||
#include "McZapkie/mctools.h"
|
||
#include "McZapkie/MOVER.h"
|
||
|
||
#define LOGVELOCITY 0
|
||
#define LOGORDERS 0
|
||
#define LOGSTOPS 1
|
||
#define LOGBACKSCAN 0
|
||
#define LOGPRESS 0
|
||
/*
|
||
|
||
Modu<EFBFBD> obs<62>uguj<75>cy sterowanie pojazdami (sk<73>adami poci<63>g<EFBFBD>w, samochodami).
|
||
Ma dzia<69>a<EFBFBD> zar<61>wno jako AI oraz przy prowadzeniu przez cz<63>owieka. W tym
|
||
drugim przypadku jedynie informuje za pomoc<6F> napis<69>w o tym, co by zrobi<62>
|
||
w tym pierwszym. Obejmuje zar<61>wno maszynist<73> jak i kierownika poci<63>gu
|
||
(dawanie sygna<6E>u do odjazdu).
|
||
|
||
Przeniesiona tutaj zosta<74>a zawarto<74><6F> ai_driver.pas przerobiona na C++.
|
||
R<EFBFBD>wnie<EFBFBD> niekt<6B>re funkcje dotycz<63>ce sk<73>ad<61>w z DynObj.cpp.
|
||
|
||
Teoria jest wtedy kiedy wszystko wiemy, ale nic nie dzia<69>a.
|
||
Praktyka jest wtedy, kiedy wszystko dzia<69>a, ale nikt nie wie dlaczego.
|
||
Tutaj <20><>czymy teori<72> z praktyk<79> - tu nic nie dzia<69>a i nikt nie wie dlaczego<67>
|
||
|
||
*/
|
||
|
||
// zrobione:
|
||
// 0. pobieranie komend z dwoma parametrami
|
||
// 1. przyspieszanie do zadanej predkosci, ew. hamowanie jesli przekroczona
|
||
// 2. hamowanie na zadanym odcinku do zadanej predkosci (ze stabilizacja przyspieszenia)
|
||
// 3. wychodzenie z sytuacji awaryjnych: bezpiecznik nadmiarowy, poslizg
|
||
// 4. przygotowanie pojazdu do drogi, zmiana kierunku ruchu
|
||
// 5. dwa sposoby jazdy - manewrowy i pociagowy
|
||
// 6. dwa zestawy psychiki: spokojny i agresywny
|
||
// 7. przejscie na zestaw spokojny jesli wystepuje duzo poslizgow lub wybic nadmiarowego.
|
||
// 8. lagodne ruszanie (przedluzony czas reakcji na 2 pierwszych nastawnikach)
|
||
// 9. unikanie jazdy na oporach rozruchowych
|
||
// 10. logowanie fizyki //Ra: nie przeniesione do C++
|
||
// 11. kasowanie czuwaka/SHP
|
||
// 12. procedury wspomagajace "patrzenie" na odlegle semafory
|
||
// 13. ulepszone procedury sterowania
|
||
// 14. zglaszanie problemow z dlugim staniem na sygnale S1
|
||
// 15. sterowanie EN57
|
||
// 16. zmiana kierunku //Ra: z przesiadk<64> po ukrotnieniu
|
||
// 17. otwieranie/zamykanie drzwi
|
||
// 18. Ra: odczepianie z zahamowaniem i podczepianie
|
||
// 19. dla Humandriver: tasma szybkosciomierza - zapis do pliku!
|
||
|
||
// do zrobienia:
|
||
// 1. kierownik pociagu
|
||
// 2. madrzejsze unikanie grzania oporow rozruchowych i silnika
|
||
// 3. unikanie szarpniec, zerwania pociagu itp
|
||
// 4. obsluga innych awarii
|
||
// 5. raportowanie problemow, usterek nie do rozwiazania
|
||
// 7. samouczacy sie algorytm hamowania
|
||
|
||
// sta<74>e
|
||
const double EasyReactionTime = 0.5; //[s] przeb<65>yski <20>wiadomo<6D>ci dla zwyk<79>ej jazdy
|
||
const double HardReactionTime = 0.2;
|
||
const double EasyAcceleration = 0.5; //[m/ss]
|
||
const double HardAcceleration = 0.9;
|
||
const double PrepareTime = 2.0; //[s] przeb<65>yski <20>wiadomo<6D>ci przy odpalaniu
|
||
bool WriteLogFlag = false;
|
||
|
||
string StopReasonTable[] = {
|
||
// przyczyny zatrzymania ruchu AI
|
||
"", // stopNone, //nie ma powodu - powinien jecha<68>
|
||
"Off", // stopSleep, //nie zosta<74> odpalony, to nie pojedzie
|
||
"Semaphore", // stopSem, //semafor zamkni<6E>ty
|
||
"Time", // stopTime, //czekanie na godzin<69> odjazdu
|
||
"End of track", // stopEnd, //brak dalszej cz<63><7A>ci toru
|
||
"Change direction", // stopDir, //trzeba stan<61><6E>, by zmieni<6E> kierunek jazdy
|
||
"Joining", // stopJoin, //zatrzymanie przy (p)odczepianiu
|
||
"Block", // stopBlock, //przeszkoda na drodze ruchu
|
||
"A command", // stopComm, //otrzymano tak<61> komend<6E> (niewiadomego pochodzenia)
|
||
"Out of station", // stopOut, //komenda wyjazdu poza stacj<63> (raczej nie powinna zatrzymywa<77>!)
|
||
"Radiostop", // stopRadio, //komunikat przekazany radiem (Radiostop)
|
||
"External", // stopExt, //przes<65>any z zewn<77>trz
|
||
"Error", // stopError //z powodu b<><62>du w obliczeniu drogi hamowania
|
||
};
|
||
|
||
//---------------------------------------------------------------------------
|
||
//---------------------------------------------------------------------------
|
||
//---------------------------------------------------------------------------
|
||
|
||
void TSpeedPos::Clear()
|
||
{
|
||
iFlags = 0; // brak flag to brak reakcji
|
||
fVelNext = -1.0; // pr<70>dko<6B><6F> bez ogranicze<7A>
|
||
fSectionVelocityDist = 0.0; //brak d<>ugo<67>ci
|
||
fDist = 0.0;
|
||
vPos = vector3(0, 0, 0);
|
||
trTrack = NULL; // brak wska<6B>nika
|
||
};
|
||
|
||
void TSpeedPos::CommandCheck()
|
||
{ // sprawdzenie typu komendy w evencie i okre<72>lenie pr<70>dko<6B>ci
|
||
TCommandType command = evEvent->Command();
|
||
double value1 = evEvent->ValueGet(1);
|
||
double value2 = evEvent->ValueGet(2);
|
||
switch (command)
|
||
{
|
||
case cm_ShuntVelocity:
|
||
// pr<70>dko<6B><6F> manewrow<6F> zapisa<73>, najwy<77>ej AI zignoruje przy analizie tabelki
|
||
fVelNext = value1; // powinno by<62> value2, bo druga okre<72>la "za"?
|
||
iFlags |= spShuntSemaphor;
|
||
break;
|
||
case cm_SetVelocity:
|
||
// w semaforze typu "m" jest ShuntVelocity dla Ms2 i SetVelocity dla S1
|
||
// SetVelocity * 0 -> mo<6D>na jecha<68>, ale stan<61><6E> przed
|
||
// SetVelocity 0 20 -> stan<61><6E> przed, potem mo<6D>na jecha<68> 20 (SBL)
|
||
// SetVelocity -1 100 -> mo<6D>na jecha<68>, przy nast<73>pnym ograniczenie (SBL)
|
||
// SetVelocity 40 -1 -> PutValues: jecha<68> 40 a<> do mini<6E>cia (koniec ograniczenia(
|
||
fVelNext = value1;
|
||
iFlags &= ~(spShuntSemaphor | spPassengerStopPoint | spStopOnSBL);
|
||
iFlags |= spSemaphor;// nie manewrowa, nie przystanek, nie zatrzyma<6D> na SBL, ale semafor
|
||
if (value1 == 0.0) // je<6A>li pierwsza zerowa
|
||
if (value2 != 0.0) // a druga nie
|
||
{ // S1 na SBL, mo<6D>na przejecha<68> po zatrzymaniu (tu nie mamy pr<70>dko<6B>ci ani odleg<65>o<EFBFBD>ci)
|
||
fVelNext = value2; // normalnie b<>dzie zezwolenie na jazd<7A>, aby si<73> usun<75><6E> z tabelki
|
||
iFlags |= spStopOnSBL; // flaga, <20>e ma zatrzyma<6D>; na pewno nie zezwoli na manewry
|
||
}
|
||
break;
|
||
case cm_SectionVelocity:
|
||
// odcinek z ograniczeniem pr<70>dko<6B>ci
|
||
fVelNext = value1;
|
||
fSectionVelocityDist = value2;
|
||
iFlags |= spSectionVel;
|
||
break;
|
||
case cm_RoadVelocity:
|
||
// pr<70>dko<6B><6F> drogowa (od tej pory b<>dzie jako domy<6D>lna najwy<77>sza)
|
||
fVelNext = value1;
|
||
iFlags |= spRoadVel;
|
||
break;
|
||
case cm_PassengerStopPoint:
|
||
// nie ma dost<73>pu do rozk<7A>adu
|
||
// przystanek, najwy<77>ej AI zignoruje przy analizie tabelki
|
||
if ((iFlags & spPassengerStopPoint) == 0)
|
||
fVelNext = 0.0; // TrainParams->IsStop()?0.0:-1.0; //na razie tak
|
||
iFlags |= spPassengerStopPoint; // niestety nie da si<73> w tym miejscu wsp<73><70>pracowa<77> z rozk<7A>adem
|
||
break;
|
||
case cm_SetProximityVelocity:
|
||
// musi zosta<74> gdy<64> inaczej nie dzia<69>aj<61> manewry
|
||
fVelNext = -1;
|
||
iFlags |= spProximityVelocity;
|
||
// fSectionVelocityDist = value2;
|
||
break;
|
||
case cm_OutsideStation:
|
||
// w trybie manewrowym: skanowa<77> od niej wstecz i stan<61><6E> po wyjechaniu za sygnalizator i
|
||
// zmieni<6E> kierunek
|
||
// w trybie poci<63>gowym: mo<6D>na przyspieszy<7A> do wskazanej pr<70>dko<6B>ci (po zjechaniu z rozjazd<7A>w)
|
||
fVelNext = -1;
|
||
iFlags |= spOutsideStation; // W5
|
||
break;
|
||
default:
|
||
// inna komenda w evencie skanowanym powoduje zatrzymanie i wys<79>anie tej komendy
|
||
iFlags &= ~(spShuntSemaphor | spPassengerStopPoint |
|
||
spStopOnSBL); // nie manewrowa, nie przystanek, nie zatrzyma<6D> na SBL
|
||
fVelNext = 0.0; // jak nieznana komenda w kom<6F>rce sygna<6E>owej, to zatrzymujemy
|
||
}
|
||
};
|
||
|
||
bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len)
|
||
{ // przeliczenie odleg<65>o<EFBFBD>ci od punktu (*p), w kierunku (*dir), zaczynaj<61>c od pojazdu
|
||
// dla kolejnych pozycji podawane s<> wsp<73><70>rz<72>dne poprzedniego obiektu w (*p)
|
||
vector3 v = vPos - *p; // wektor od poprzedniego obiektu (albo pojazdu) do punktu zmiany
|
||
fDist =
|
||
v.Length(); // d<>ugo<67><6F> wektora to odleg<65>o<EFBFBD><6F> pomi<6D>dzy czo<7A>em a sygna<6E>em albo pocz<63>tkiem toru
|
||
// v.SafeNormalize(); //normalizacja w celu okre<72>lenia znaku (nie potrzebna?)
|
||
if (len == 0.0)
|
||
{ // je<6A>eli liczymy wzgl<67>dem pojazdu
|
||
double iska = dir ? dir->x * v.x + dir->z * v.z :
|
||
fDist; // iloczyn skalarny to rzut na chwilow<6F> prost<73> ruchu
|
||
if (iska < 0.0) // iloczyn skalarny jest ujemny, gdy punkt jest z ty<74>u
|
||
{ // je<6A>li co<63> jest z ty<74>u, to dok<6F>adna odleg<65>o<EFBFBD><6F> nie ma ju<6A> wi<77>kszego znaczenia
|
||
fDist = -fDist; // potrzebne do badania wyjechania sk<73>adem poza ograniczenie
|
||
if (iFlags & spElapsed) // 32 ustawione, gdy obiekt ju<6A> zosta<74> mini<6E>ty
|
||
{ // je<6A>li mini<6E>ty (musi by<62> mini<6E>ty r<>wnie<69> przez ko<6B>c<EFBFBD>wk<77> sk<73>adu)
|
||
}
|
||
else
|
||
{
|
||
iFlags ^= spElapsed; // 32-mini<6E>ty - b<>dziemy liczy<7A> odleg<65>o<EFBFBD><6F> wzgl<67>dem przeciwnego ko<6B>ca
|
||
// toru (nadal mo<6D>e by<62> z przodu i ogranicza<7A>)
|
||
if ((iFlags & 0x43) == 3) // tylko je<6A>li (istotny) tor, bo eventy s<> punktowe
|
||
if (trTrack) // mo<6D>e by<62> NULL, je<6A>li koniec toru (????)
|
||
vPos =
|
||
(iFlags & spReverse) ?
|
||
trTrack->CurrentSegment()->FastGetPoint_0() :
|
||
trTrack->CurrentSegment()->FastGetPoint_1(); // drugi koniec istotny
|
||
}
|
||
}
|
||
else if (fDist < 50.0) // przy du<64>ym k<>cie <20>uku iloczyn skalarny bardziej zani<6E>y odleg<65>o<EFBFBD><6F>
|
||
// ni<6E> ci<63>ciwa
|
||
fDist = iska; // ale przy ma<6D>ych odleg<65>o<EFBFBD>ciach rzut na chwilow<6F> prost<73> ruchu da
|
||
// dok<6F>adniejsze warto<74>ci
|
||
}
|
||
if (fDist > 0.0) // nie mo<6D>e by<62> 0.0, a przypadkiem mog<6F>o by si<73> trafi<66> i by<62>o by <20>le
|
||
if ((iFlags & spElapsed) == 0) // 32 ustawione, gdy obiekt ju<6A> zosta<74> mini<6E>ty
|
||
{ // je<6A>li obiekt nie zosta<74> mini<6E>ty, mo<6D>na od niego zlicza<7A> narastaj<61>co (inaczej mo<6D>e by<62>
|
||
// problem z wektorem kierunku)
|
||
len = fDist = len + fDist; // zliczanie dlugo<67>ci narastaj<61>co
|
||
*p = vPos; // nowy punkt odniesienia
|
||
*dir = Normalize(v); // nowy wektor kierunku od poprzedniego obiektu do aktualnego
|
||
}
|
||
if (iFlags & spTrack) // je<6A>li tor
|
||
{
|
||
if (trTrack) // mo<6D>e by<62> NULL, je<6A>li koniec toru (???)
|
||
{
|
||
fVelNext = trTrack->VelocityGet(); // aktualizacja pr<70>dko<6B>ci (mo<6D>e by<62> zmieniana
|
||
// eventem)
|
||
int i;
|
||
if ((i = iFlags & 0xF0000000) != 0)
|
||
{ // je<6A>li skrzy<7A>owanie, ograniczy<7A> pr<70>dko<6B><6F> przy skr<6B>caniu
|
||
if (abs(i) > 0x10000000) //<2F>1 to jazda na wprost, <20>2 nieby te<74>, ale z przeci<63>ciem
|
||
// g<><67>wnej drogi - chyba <20>e jest r<>wnorz<72>dne...
|
||
fVelNext = 30.0; // uzale<6C>ni<6E> pr<70>dko<6B><6F> od promienia; albo niech b<>dzie
|
||
// ograniczona w skrzy<7A>owaniu (velocity z ujemn<6D> warto<74>ci<63>)
|
||
if ((iFlags & spElapsed) == 0) // je<6A>li nie wjecha<68>
|
||
if (trTrack->iNumDynamics > 0) // a skrzy<7A>owanie zawiera pojazd
|
||
{
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("Tor " + trTrack->NameGet() + " zajety przed pojazdem. Num=" +
|
||
to_string(trTrack->iNumDynamics) + "Dist= " + to_string(fDist));
|
||
fVelNext =
|
||
0.0; // to zabroni<6E> wjazdu (chyba <20>e ten z przodu te<74> jedzie prosto)
|
||
}
|
||
}
|
||
if (iFlags & spSwitch) // je<6A>li odcinek zmienny
|
||
{
|
||
if (bool(trTrack->GetSwitchState() & 1) !=
|
||
bool(iFlags & spSwitchStatus)) // czy stan si<73> zmieni<6E>?
|
||
{ // Ra: zak<61>adam, <20>e s<> tylko 2 mo<6D>liwe stany
|
||
iFlags ^= spSwitchStatus;
|
||
// fVelNext=trTrack->VelocityGet(); //nowa pr<70>dko<6B><6F>
|
||
if ((iFlags & spElapsed) == 0)
|
||
return true; // jeszcze trzeba skanowanie wykona<6E> od tego toru
|
||
// problem jest chyba, je<6A>li zwrotnica si<73> prze<7A>o<EFBFBD>y zaraz po zjechaniu z niej
|
||
// na Mydelniczce potrafi skanowa<77> na wprost mimo pojechania na bok
|
||
}
|
||
// poni<6E>sze nie dotyczy trybu <20><>czenia?
|
||
if ((iFlags & spElapsed) ? false :
|
||
trTrack->iNumDynamics >
|
||
0) // je<6A>li jeszcze nie wjechano na tor, a co<63> na nim jest
|
||
{
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("Rozjazd " + trTrack->NameGet() + " zajety przed pojazdem. Num=" +
|
||
to_string(trTrack->iNumDynamics) + "Dist= "+ to_string(fDist));
|
||
//fDist -= 30.0;
|
||
fVelNext = 0.0; // to niech stanie w zwi<77>kszonej odleg<65>o<EFBFBD>ci
|
||
// else if (fVelNext==0.0) //je<6A>li zosta<74>a wyzerowana
|
||
// fVelNext=trTrack->VelocityGet(); //odczyt pr<70>dko<6B>ci
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if (iFlags & spEvent) // je<6A>li event
|
||
{ // odczyt kom<6F>rki pami<6D>ci najlepiej by by<62>o zrobi<62> jako notyfikacj<63>, czyli zmiana kom<6F>rki
|
||
// wywo<77>a jak<61><6B> podan<61> funkcj<63>
|
||
CommandCheck(); // sprawdzenie typu komendy w evencie i okre<72>lenie pr<70>dko<6B>ci
|
||
}
|
||
return false;
|
||
};
|
||
|
||
std::string TSpeedPos::GetName()
|
||
{
|
||
if (iFlags & spTrack) // je<6A>li tor
|
||
return trTrack->NameGet();
|
||
else if (iFlags & spEvent) // je<6A>li event
|
||
return evEvent->asName;
|
||
}
|
||
|
||
std::string TSpeedPos::TableText()
|
||
{ // pozycja tabelki pr<70>dko<6B>ci
|
||
if (iFlags & spEnabled)
|
||
{ // o ile pozycja istotna
|
||
return "Flags=#" + to_hex_str(iFlags, 8) + ", Dist=" + to_string(fDist, 1, 7) +
|
||
", Vel=" + to_string(fVelNext) + ", Name=" + GetName();
|
||
//if (iFlags & spTrack) // je<6A>li tor
|
||
// return "Flags=#" + IntToHex(iFlags, 8) + ", Dist=" + FloatToStrF(fDist, ffFixed, 7, 1) +
|
||
// ", Vel=" + AnsiString(fVelNext) + ", Track=" + trTrack->NameGet();
|
||
//else if (iFlags & spEvent) // je<6A>li event
|
||
// return "Flags=#" + IntToHex(iFlags, 8) + ", Dist=" + FloatToStrF(fDist, ffFixed, 7, 1) +
|
||
// ", Vel=" + AnsiString(fVelNext) + ", Event=" + evEvent->asName;
|
||
}
|
||
return "Empty";
|
||
}
|
||
|
||
bool TSpeedPos::IsProperSemaphor(TOrders order)
|
||
{ // sprawdzenie czy semafor jest zgodny z trybem jazdy
|
||
if (order < 0x40) // Wait_for_orders, Prepare_engine, Change_direction, Connect, Disconnect, Shunt
|
||
{
|
||
if (iFlags & (spSemaphor | spShuntSemaphor))
|
||
return true;
|
||
else if (iFlags & spOutsideStation)
|
||
return true;
|
||
}
|
||
else if (order & Obey_train)
|
||
{
|
||
if (iFlags & spSemaphor)
|
||
return true;
|
||
}
|
||
return false; // true gdy zatrzymanie, wtedy nie ma po co skanowa<77> dalej
|
||
}
|
||
|
||
bool TSpeedPos::Set(TEvent *event, double dist, TOrders order)
|
||
{ // zapami<6D>tanie zdarzenia
|
||
fDist = dist;
|
||
iFlags = spEnabled | spEvent; // event+istotny
|
||
evEvent = event;
|
||
vPos = event->PositionGet(); // wsp<73><70>rz<72>dne eventu albo kom<6F>rki pami<6D>ci (zrzutowa<77> na tor?)
|
||
CommandCheck(); // sprawdzenie typu komendy w evencie i okre<72>lenie pr<70>dko<6B>ci
|
||
// zale<6C>nie od trybu sprawdzenie czy jest tutaj gdzie<69> semafor lub tarcza manewrowa
|
||
// je<6A>li wskazuje stop wtedy wystawiamy true jako koniec sprawdzania
|
||
// WriteLog("EventSet: Vel=" + AnsiString(fVelNext) + " iFlags=" + AnsiString(iFlags) + " order="+AnsiString(order));
|
||
if (order < 0x40) // Wait_for_orders, Prepare_engine, Change_direction, Connect, Disconnect, Shunt
|
||
{
|
||
if (iFlags & (spSemaphor | spShuntSemaphor) && fVelNext == 0.0)
|
||
return true;
|
||
else if (iFlags & spOutsideStation)
|
||
return true;
|
||
}
|
||
else if (order & Obey_train)
|
||
{
|
||
if (iFlags & spSemaphor && fVelNext == 0.0)
|
||
return true;
|
||
}
|
||
return false; // true gdy zatrzymanie, wtedy nie ma po co skanowa<77> dalej
|
||
};
|
||
|
||
void TSpeedPos::Set(TTrack *track, double dist, int flag)
|
||
{ // zapami<6D>tanie zmiany pr<70>dko<6B>ci w torze
|
||
fDist = dist; // odleg<65>o<EFBFBD><6F> do pocz<63>tku toru
|
||
trTrack = track; // TODO: (t) mo<6D>e by<62> NULL i nie odczytamy ko<6B>ca poprzedniego :/
|
||
if (trTrack)
|
||
{
|
||
iFlags = flag | (trTrack->eType == tt_Normal ? 2 : 10); // zapami<6D>tanie kierunku wraz z typem
|
||
if (iFlags & spSwitch)
|
||
if (trTrack->GetSwitchState() & 1)
|
||
iFlags |= spSwitchStatus;
|
||
fVelNext = trTrack->VelocityGet();
|
||
if (trTrack->iDamageFlag & 128)
|
||
fVelNext = 0.0; // je<6A>li uszkodzony, to te<74> st<73>j
|
||
if (iFlags & spEnd)
|
||
fVelNext = (trTrack->iCategoryFlag & 1) ?
|
||
0.0 :
|
||
20.0; // je<6A>li koniec, to poci<63>g st<73>j, a samoch<63>d zwolnij
|
||
vPos = (bool(iFlags & spReverse) != bool(iFlags & spEnd)) ?
|
||
trTrack->CurrentSegment()->FastGetPoint_1() :
|
||
trTrack->CurrentSegment()->FastGetPoint_0();
|
||
}
|
||
};
|
||
|
||
//---------------------------------------------------------------------------
|
||
//---------------------------------------------------------------------------
|
||
//---------------------------------------------------------------------------
|
||
|
||
void TController::TableClear()
|
||
{ // wyczyszczenie tablicy
|
||
iFirst = iLast = 0;
|
||
iTableDirection = 0; // nieznany
|
||
for (int i = 0; i < iSpeedTableSize; ++i) // czyszczenie tabeli pr<70>dko<6B>ci
|
||
sSpeedTable[i].Clear();
|
||
tLast = NULL;
|
||
fLastVel = -1;
|
||
eSignSkip = NULL; // nic nie pomijamy
|
||
};
|
||
|
||
TEvent * TController::CheckTrackEvent(double fDirection, TTrack *Track)
|
||
{ // sprawdzanie event<6E>w na podanym torze do podstawowego skanowania
|
||
TEvent *e = (fDirection > 0) ? Track->evEvent2 : Track->evEvent1;
|
||
if (!e)
|
||
return NULL;
|
||
if (e->bEnabled)
|
||
return NULL;
|
||
// jednak wszystkie W4 do tabelki, bo jej czyszczenie na przystanku wprowadza zamieszanie
|
||
return e;
|
||
}
|
||
|
||
bool TController::TableAddNew()
|
||
{ // zwi<77>kszenie u<>ytej tabelki o jeden rekord
|
||
iLast = (iLast + 1) % iSpeedTableSize;
|
||
// TODO: jeszcze sprawdzi<7A>, czy si<73> na iFirst nie na<6E>o<EFBFBD>y
|
||
// TODO: wstawi<77> tu wywo<77>anie odtykacza - teraz jest to w TableTraceRoute()
|
||
// TODO: je<6A>li ostatnia pozycja zaj<61>ta, ustawia<69> dodatkowe flagi - teraz jest to w
|
||
// TableTraceRoute()
|
||
// TODO: przyda<64>o by si<73> te<74> posortowa<77> tabelk<6C> wg odleg<65>o<EFBFBD>ci (ale nie w tym miejscu)
|
||
return true; // false gdy si<73> na<6E>o<EFBFBD>y
|
||
};
|
||
|
||
bool TController::TableNotFound(TEvent *e)
|
||
{ // sprawdzenie, czy nie zosta<74> ju<6A> dodany do tabelki (np. podw<64>jne W4 robi problemy)
|
||
int j = (iLast + 1) % iSpeedTableSize; // j, aby sprawdzi<7A> te<74> ostatni<6E> pozycj<63>
|
||
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)
|
||
{
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("TableNotFound: Event already in SpeedTable: " + sSpeedTable[i].evEvent->asName);
|
||
return false; // ju<6A> jest, drugi raz dodawa<77> nie ma po co
|
||
}
|
||
return true; // nie ma, czyli mo<6D>na doda<64>
|
||
};
|
||
|
||
void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
||
{ // skanowanie trajektorii na odleg<65>o<EFBFBD><6F> (fDistance) od (pVehicle) w kierunku przodu sk<73>adu i
|
||
// uzupe<70>nianie tabelki
|
||
// WriteLog("Starting TableTraceRoute");
|
||
if (!iDirection) // kierunek pojazdu z nap<61>dem
|
||
{ // je<6A>li kierunek jazdy nie jest okreslony
|
||
iTableDirection = 0; // czekamy na ustawienie kierunku
|
||
}
|
||
TTrack *pTrack; // zaczynamy od ostatniego analizowanego toru
|
||
// double fDistChVel=-1; //odleg<65>o<EFBFBD><6F> do toru ze zmian<61> pr<70>dko<6B>ci
|
||
double fTrackLength; // d<>ugo<67><6F> aktualnego toru (kr<6B>tsza dla pierwszego)
|
||
double fCurrentDistance; // aktualna przeskanowana d<>ugo<67><6F>
|
||
TEvent *pEvent;
|
||
double fLastDir; // kierunek na ostatnim torze
|
||
if (iTableDirection != iDirection)
|
||
{ // je<6A>li zmiana kierunku, zaczynamy od toru ze wskazanym pojazdem
|
||
pTrack = pVehicle->RaTrackGet(); // odcinek, na kt<6B>rym stoi
|
||
fLastDir = pVehicle->DirectionGet() *
|
||
pVehicle->RaDirectionGet(); // ustalenie kierunku skanowania na torze
|
||
fCurrentDistance = 0; // na razie nic nie przeskanowano
|
||
fTrackLength = pVehicle->RaTranslationGet(); // pozycja na tym torze (odleg<65>o<EFBFBD><6F> od Point1)
|
||
if (fLastDir > 0) // je<6A>li w kierunku Point2 toru
|
||
fTrackLength =
|
||
pTrack->Length() - fTrackLength; // przeskanowana zostanie odleg<65>o<EFBFBD><6F> do Point2
|
||
fLastVel = pTrack->VelocityGet(); // aktualna pr<70>dko<6B><6F>
|
||
iTableDirection =
|
||
iDirection; // ustalenie w jakim kierunku jest wype<70>niana tabelka wzgl<67>dem pojazdu
|
||
iFirst = iLast = 0;
|
||
tLast = NULL; //<2F>aden nie sprawdzony
|
||
}
|
||
else
|
||
{ // kontynuacja skanowania od ostatnio sprawdzonego toru (w ostatniej pozycji zawsze jest tor)
|
||
// WriteLog("TableTraceRoute: check last track");
|
||
if (sSpeedTable[iLast].iFlags & spEndOfTable) // zatkanie
|
||
{ // je<6A>li zape<70>ni<6E>a si<73> tabelka
|
||
if ((iLast + 1) % iSpeedTableSize == iFirst) // je<6A>li nadal jest zape<70>niona
|
||
{
|
||
TablePurger(); // nic si<73> nie da zrobi<62>
|
||
return;
|
||
}
|
||
if ((iLast + 2) % iSpeedTableSize == iFirst) // musi by<62> jeszcze miejsce wolne na
|
||
// ewentualny event, bo tor jeszcze nie
|
||
// sprawdzony
|
||
{
|
||
TablePurger();
|
||
return; // ju<6A> lepiej, ale jeszcze nie tym razem
|
||
}
|
||
sSpeedTable[iLast].iFlags &= 0xBE; // kontynuowa<77> pr<70>by doskanowania
|
||
}
|
||
// znaleziono semafor lub tarcz<63> lub tor z pr<70>dko<6B>ci<63> zero
|
||
// trzeba sprawdzi<7A> czy to nada<64> semafor
|
||
// WriteLog("TableTraceRoute: "+OwnerName()+" check semaphor... ");
|
||
// if (sSemNext)
|
||
// WriteLog(sSemNext->TableText());
|
||
if (sSemNextStop &&
|
||
sSemNextStop->fVelNext ==
|
||
0.0) // je<6A>li jest nast<73>pny semafor to sprawdzamy czy to on nada<64> zero
|
||
{
|
||
// WriteLog("TableTraceRoute: "+sSemNext->TableText());
|
||
if ((OrderCurrentGet() & Obey_train) && (sSemNextStop->iFlags & spSemaphor))
|
||
return;
|
||
else if ((OrderCurrentGet() < 0x40) &&
|
||
(sSemNextStop->iFlags & (spSemaphor | spShuntSemaphor | spOutsideStation)))
|
||
return;
|
||
}
|
||
pTrack = sSpeedTable[iLast].trTrack; // ostatnio sprawdzony tor
|
||
if (!pTrack)
|
||
return; // koniec toru, to nie ma co sprawdza<7A> (nie ma prawa tak by<62>)
|
||
fLastDir = sSpeedTable[iLast].iFlags & spReverse ?
|
||
-1.0 :
|
||
1.0; // flaga ustawiona, gdy Point2 toru jest bli<6C>ej
|
||
fCurrentDistance = sSpeedTable[iLast].fDist; // aktualna odleg<65>o<EFBFBD><6F> do jego Point1
|
||
fTrackLength =
|
||
sSpeedTable[iLast].iFlags & (spElapsed | spEnd) ? 0.0 : pTrack->Length(); // nie dolicza<7A> d<>ugo<67>ci gdy:
|
||
// 32-mini<6E>ty pocz<63>tek,
|
||
// 64-jazda do ko<6B>ca toru
|
||
}
|
||
if (fCurrentDistance < fDistance)
|
||
{ // je<6A>li w og<6F>le jest po co analizowa<77>
|
||
// WriteLog("TableTraceRoute: checking next tracks");
|
||
--iLast; // jak co<63> si<73> znajdzie, zostanie wpisane w t<> pozycj<63>, kt<6B>r<EFBFBD> w<>a<EFBFBD>nie odczytano
|
||
while (fCurrentDistance < fDistance)
|
||
{
|
||
if (pTrack != tLast) // ostatni zapisany w tabelce nie by<62> jeszcze sprawdzony
|
||
{ // je<6A>li tor nie by<62> jeszcze sprawdzany
|
||
// if (pTrack)
|
||
// WriteLog("TableTraceRoute: " + OwnerName() + " checking track " +
|
||
// pTrack->NameGet());
|
||
if ((pEvent = CheckTrackEvent(fLastDir, pTrack)) !=
|
||
NULL) // je<6A>li jest semafor na tym torze
|
||
{ // trzeba sprawdzi<7A> tabelk<6C>, bo dodawanie drugi raz tego samego przystanku nie
|
||
// jest korzystne
|
||
if (TableNotFound(pEvent)) // je<6A>li nie ma
|
||
if (TableAddNew())
|
||
{
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("TableTraceRoute: new event found " + pEvent->asName + " by " + OwnerName());
|
||
if (sSpeedTable[iLast].Set( pEvent, fCurrentDistance, OrderCurrentGet())) // dodanie odczytu sygna<6E>u
|
||
{
|
||
fDistance = fCurrentDistance; // je<6A>li sygna<6E> stop, to nie ma
|
||
// potrzeby dalej skanowa<77>
|
||
sSemNextStop = &sSpeedTable[iLast];
|
||
if (!sSemNext)
|
||
sSemNext = &sSpeedTable[iLast];
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("Signal stop. Next Semaphor ", false);
|
||
if (sSemNextStop)
|
||
{
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog(sSemNextStop->GetName());
|
||
}
|
||
else
|
||
{
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("none");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (sSpeedTable[iLast].IsProperSemaphor(OrderCurrentGet()) &&
|
||
sSemNext == NULL)
|
||
sSemNext =
|
||
&sSpeedTable[iLast]; // sprawdzamy czy pierwszy na drodze
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("Signal forward. Next Semaphor ", false);
|
||
if (sSemNext)
|
||
{
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog(sSemNext->GetName());
|
||
}
|
||
else
|
||
{
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("none");
|
||
}
|
||
}
|
||
}
|
||
} // event dodajemy najpierw, <20>eby m<>c sprawdzi<7A>, czy tor zosta<74> dodany po
|
||
// odczytaniu pr<70>dko<6B>ci nast<73>pnego
|
||
if ((pTrack->VelocityGet() == 0.0) // zatrzymanie
|
||
|| (pTrack->iAction) // je<6A>li tor ma w<>asno<6E>ci istotne dla skanowania
|
||
|| (pTrack->VelocityGet() != fLastVel)) // nast<73>puje zmiana pr<70>dko<6B>ci
|
||
{ // odcinek dodajemy do tabelki, gdy jest istotny dla ruchu
|
||
if (TableAddNew())
|
||
{ // teraz dodatkowo zapami<6D>tanie wybranego segmentu dla skrzy<7A>owania
|
||
sSpeedTable[iLast].Set(
|
||
pTrack, fCurrentDistance,
|
||
fLastDir < 0 ?
|
||
5 :
|
||
1); // dodanie odcinka do tabelki z flag<61> kierunku wej<65>cia
|
||
if (pTrack->eType == tt_Cross) // na skrzy<7A>owaniach trzeba wybra<72> segment,
|
||
// po kt<6B>rym pojedzie pojazd
|
||
{ // dopiero tutaj jest ustalany kierunek segmentu na skrzy<7A>owaniu
|
||
sSpeedTable[iLast].iFlags |=
|
||
(pTrack->CrossSegment((fLastDir < 0) ? tLast->iPrevDirection :
|
||
tLast->iNextDirection,
|
||
iRouteWanted) &
|
||
15)
|
||
<< 28; // ostatnie 4 bity pola flag
|
||
sSpeedTable[iLast].iFlags &=
|
||
~spReverse; // usuni<6E>cie flagi kierunku, bo mo<6D>e by<62> b<><62>dna
|
||
if (sSpeedTable[iLast].iFlags < 0)
|
||
sSpeedTable[iLast].iFlags |=
|
||
spReverse; // ustawienie flagi kierunku na podstawie wybranego segmentu
|
||
if (int(fLastDir) * sSpeedTable[iLast].iFlags < 0)
|
||
fLastDir = -fLastDir;
|
||
if (AIControllFlag) // dla AI na razie losujemy kierunek na kolejnym
|
||
// skrzy<7A>owaniu
|
||
iRouteWanted = 1 + random(3);
|
||
}
|
||
}
|
||
}
|
||
else if ((pTrack->fRadius != 0.0) // odleg<65>o<EFBFBD><6F> na <20>uku lepiej aproksymowa<77> ci<63>ciwami
|
||
|| (tLast ? tLast->fRadius != 0.0 : false)) // koniec <20>uku te<74> jest istotny
|
||
{ // albo dla liczenia odleg<65>o<EFBFBD>ci przy pomocy ci<63>ciw - te usuwa<77> po przejechaniu
|
||
if (TableAddNew())
|
||
sSpeedTable[iLast].Set(pTrack, fCurrentDistance,
|
||
fLastDir < 0 ? 0x85 :
|
||
0x81); // dodanie odcinka do tabelki
|
||
// 0x85 = spEnabled, spReverse, SpCurve
|
||
}
|
||
}
|
||
fCurrentDistance +=
|
||
fTrackLength; // doliczenie kolejnego odcinka do przeskanowanej d<>ugo<67>ci
|
||
tLast = pTrack; // odhaczenie, <20>e sprawdzony
|
||
// Track->ScannedFlag=true; //do pokazywania przeskanowanych tor<6F>w
|
||
fLastVel = pTrack->VelocityGet(); // pr<70>dko<6B><6F> na poprzednio sprawdzonym odcinku
|
||
pTrack = pTrack->Neightbour(
|
||
(pTrack->eType == tt_Cross) ? (sSpeedTable[iLast].iFlags >> 28) : int(fLastDir),
|
||
fLastDir); // mo<6D>e by<62> NULL
|
||
/*
|
||
if (fLastDir>0)
|
||
{//je<6A>li szukanie od Point1 w kierunku Point2
|
||
pTrack=pTrack->CurrentNext(); //mo<6D>e by<62> NULL
|
||
if (pTrack) //je<6A>li dalej brakuje toru, to zostajemy na tym samym, z t<> sam<61>
|
||
orientacj<63>
|
||
if (tLast->iNextDirection)
|
||
fLastDir=-fLastDir; //mo<6D>na by zami<6D>ta<74> i zmieni<6E> tylko je<6A>li jest pTrack
|
||
}
|
||
else //if (fDirection<0)
|
||
{//je<6A>li szukanie od Point2 w kierunku Point1
|
||
pTrack=pTrack->CurrentPrev(); //mo<6D>e by<62> NULL
|
||
if (pTrack) //je<6A>li dalej brakuje toru, to zostajemy na tym samym, z t<> sam<61>
|
||
orientacj<63>
|
||
if (!tLast->iPrevDirection)
|
||
fLastDir=-fLastDir;
|
||
}
|
||
*/
|
||
if (pTrack)
|
||
{ // je<6A>li kolejny istnieje
|
||
if (tLast)
|
||
if (pTrack->VelocityGet() < 0 ? tLast->VelocityGet() > 0 :
|
||
pTrack->VelocityGet() > tLast->VelocityGet())
|
||
{ // je<6A>li kolejny ma wi<77>ksz<73> pr<70>dko<6B><6F> ni<6E> poprzedni, to zapami<6D>ta<74> poprzedni
|
||
// (do czasu wyjechania)
|
||
if ((sSpeedTable[iLast].iFlags & 3) == 3 ?
|
||
(sSpeedTable[iLast].trTrack != tLast) :
|
||
true) // je<6A>li nie by<62> dodany do tabelki
|
||
if (TableAddNew())
|
||
sSpeedTable[iLast].Set(
|
||
tLast, fCurrentDistance,
|
||
(fLastDir > 0 ? pTrack->iPrevDirection :
|
||
pTrack->iNextDirection) ?
|
||
1 :
|
||
5); // zapisanie toru z ograniczeniem pr<70>dko<6B>ci
|
||
}
|
||
if (((iLast + 3) % iSpeedTableSize == iFirst) ?
|
||
true :
|
||
((iLast + 2) % iSpeedTableSize == iFirst)) // czy tabelka si<73> nie zatka?
|
||
{ // jest ryzyko nieznalezienia ograniczenia - ograniczy<7A> pr<70>dko<6B><6F> do pozwalaj<61>cej
|
||
// na zatrzymanie na ko<6B>cu przeskanowanej drogi
|
||
TablePurger(); // usun<75><6E> pilnie zb<7A>dne pozycje
|
||
if (((iLast + 3) % iSpeedTableSize == iFirst) ?
|
||
true :
|
||
((iLast + 2) % iSpeedTableSize == iFirst)) // czy tabelka si<73> nie zatka?
|
||
{ // je<6A>li odtykacz nie pom<6F>g<EFBFBD> (TODO: zwi<77>kszy<7A> rozmiar tabelki)
|
||
if (TableAddNew())
|
||
sSpeedTable[iLast].Set(
|
||
pTrack, fCurrentDistance,
|
||
fLastDir < 0 ?
|
||
0x10045 :
|
||
0x10041); // zapisanie toru jako ko<6B>cowego (ogranicza pr<70>dkos<6F>)
|
||
// zapisa<73> w logu, <20>e nale<6C>y poprawi<77> sceneri<72>?
|
||
return; // nie skanujemy dalej, bo nie ma miejsca
|
||
}
|
||
}
|
||
fTrackLength = pTrack->Length(); // zwi<77>kszenie skanowanej odleg<65>o<EFBFBD>ci tylko je<6A>li
|
||
// istnieje dalszy tor
|
||
}
|
||
else
|
||
{ // definitywny koniec skanowania, chyba <20>e dalej puszczamy samoch<63>d po gruncie...
|
||
if (TableAddNew()) // kolejny, bo si<73> cofn<66>li<6C>my o 1
|
||
sSpeedTable[iLast].Set(
|
||
tLast, fCurrentDistance,
|
||
fLastDir < 0 ? 0x45 : 0x41); // zapisanie ostatniego sprawdzonego toru
|
||
return; // to ostatnia pozycja, bo NULL nic nie da, a mo<6D>e si<73> podpi<70><69> obrotnica,
|
||
// czy jakie<69> transportery
|
||
}
|
||
}
|
||
if (TableAddNew())
|
||
sSpeedTable[iLast].Set(pTrack, fCurrentDistance,
|
||
fLastDir < 0 ? 4 : 0); // zapisanie ostatniego sprawdzonego toru
|
||
}
|
||
};
|
||
|
||
void TController::TableCheck(double fDistance)
|
||
{ // przeliczenie odleg<65>o<EFBFBD>ci w tabelce, ewentualnie doskanowanie (bez analizy pr<70>dko<6B>ci itp.)
|
||
if (iTableDirection != iDirection)
|
||
TableTraceRoute(fDistance,
|
||
pVehicles[1]); // jak zmiana kierunku, to skanujemy od ko<6B>ca sk<73>adu
|
||
else if (iTableDirection)
|
||
{ // trzeba sprawdzi<7A>, czy co<63> si<73> zmieni<6E>o
|
||
vector3 dir =
|
||
pVehicles[0]->VectorFront() * pVehicles[0]->DirectionGet(); // wektor kierunku jazdy
|
||
vector3 pos = pVehicles[0]->HeadPosition(); // zaczynamy od pozycji pojazdu
|
||
// double lastspeed=-1; //pr<70>dko<6B><6F> na torze do usuni<6E>cia
|
||
double len = 0.0; // odleg<65>o<EFBFBD><6F> b<>dziemy zlicza<7A> narastaj<61>co
|
||
for (int i = iFirst; i != iLast; i = (i + 1) % iSpeedTableSize)
|
||
{ // aktualizacja rekord<72>w z wyj<79>tkiem ostatniego
|
||
if (sSpeedTable[i].iFlags & spEnabled) // je<6A>li pozycja istotna
|
||
{
|
||
if (sSpeedTable[i].Update(&pos, &dir, len))
|
||
{
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("TableCheck: Switch change. Delete next entries. (" + sSpeedTable[i].trTrack->NameGet() + ")");
|
||
int k = (iLast + 1) % iSpeedTableSize; // skanujemy razem z ostatni<6E> pozycj<63>
|
||
for (int j = (i+1) % iSpeedTableSize; j != k; j = (j + 1) % iSpeedTableSize)
|
||
{ // kasowanie wszystkich rekord<72>w za zmienion<6F> zwrotnic<69>
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("TableCheck: Delete from table: " + sSpeedTable[j].GetName());
|
||
sSpeedTable[j].iFlags = 0;
|
||
if (&sSpeedTable[j] == sSemNext)
|
||
sSemNext = NULL; // przy kasowaniu tabelki zrzucamy tak<61>e semafor
|
||
if (&sSpeedTable[j] == sSemNextStop)
|
||
sSemNextStop = NULL; // przy kasowaniu tabelki zrzucamy tak<61>e semafor
|
||
}
|
||
if (Global::iWriteLogEnabled & 8)
|
||
{
|
||
WriteLog("TableCheck: Delete entries OK.");
|
||
WriteLog("TableCheck: New last element: " + sSpeedTable[i].GetName());
|
||
}
|
||
iLast = i; // pokazujemy gdzie jest ostatni kawa<77>ek
|
||
break; // nie kontynuujemy p<>tli, trzeba doskanowa<77> ci<63>g dalszy
|
||
}
|
||
if (sSpeedTable[i].iFlags & spTrack) // je<6A>li odcinek
|
||
{
|
||
if (sSpeedTable[i].fDist < -fLength) // a sk<73>ad wyjecha<68> ca<63><61> d<>ugo<67>ci<63> poza
|
||
{ // degradacja pozycji
|
||
// WriteLog( "TableCheck: Track is behind. Delete from table: " + sSpeedTable[i].trTrack->NameGet());
|
||
sSpeedTable[i].iFlags &= ~spEnabled; // nie liczy si<73>
|
||
}
|
||
else if ((sSpeedTable[i].iFlags & 0xF0000028) ==
|
||
spElapsed) // jest z ty<74>u (najechany) i nie jest zwrotnic<69> ani skrzy<7A>owaniem
|
||
if (sSpeedTable[i].fVelNext < 0) // a nie ma ograniczenia pr<70>dko<6B>ci
|
||
{
|
||
sSpeedTable[i].iFlags =
|
||
0; // to nie ma go po co trzyma<6D> (odtykacz usunie ze <20>rodka)
|
||
// WriteLog("TableCheck: Track without speed. Delete from table: " + sSpeedTable[i].trTrack->NameGet());
|
||
}
|
||
}
|
||
else if (sSpeedTable[i].iFlags & spEvent) // je<6A>li event
|
||
{
|
||
if (sSpeedTable[i].fDist < (sSpeedTable[i].evEvent->Type == tp_PutValues ?
|
||
-fLength :
|
||
0)) // je<6A>li jest z ty<74>u
|
||
if ((mvOccupied->CategoryFlag & 1) ? false :
|
||
sSpeedTable[i].fDist < -fLength)
|
||
{ // poci<63>g staje zawsze, a samoch<63>d tylko je<6A>li nie przejedzie ca<63><61>
|
||
// d<>ugo<67>ci<63> (mo<6D>e by<62> zaskoczony zmian<61>)
|
||
// 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<73>aj<61> komendy
|
||
}
|
||
}
|
||
// if (sSpeedTable[i].fDist<-20.0*fLength) //je<6A>li to co<63> jest 20 razy dalej ni<6E>
|
||
// d<>ugo<67><6F> sk<73>adu
|
||
//{sSpeedTable[i].iFlags&=~1; //to jest to jakby b<><62>d w scenerii
|
||
// //WriteLog("Error: too distant object in scan table");
|
||
//}
|
||
// if (sSpeedTable[i].fDist>20.0*fLength) //je<6A>li to co<63> jest 20 razy dalej ni<6E>
|
||
// d<>ugo<67><6F> sk<73>adu
|
||
//{sSpeedTable[i].iFlags&=~1; //to jest to jakby b<><62>d w scenerii
|
||
// //WriteLog("Error: too distant object in scan table");
|
||
//}
|
||
}
|
||
if (i == iFirst) // je<6A>li jest pierwsz<73> pozycj<63> tabeli
|
||
{ // pozbycie si<73> pocz<63>tkowej pozycji
|
||
if ((sSpeedTable[i].iFlags & 1) ==
|
||
0) // je<6A>li pozycja istotna (po Update() mo<6D>e si<73> zmieni<6E>)
|
||
// if (iFirst!=iLast) //ostatnia musi zosta<74> - to za<7A>atwia for()
|
||
iFirst = (iFirst + 1) %
|
||
iSpeedTableSize; // kolejne sprawdzanie b<>dzie ju<6A> od nast<73>pnej pozycji
|
||
}
|
||
}
|
||
sSpeedTable[iLast].Update(&pos, &dir, len); // aktualizacja ostatniego
|
||
// WriteLog("TableCheck: Upate last track. Dist=" + AnsiString(sSpeedTable[iLast].fDist));
|
||
if (sSpeedTable[iLast].fDist < fDistance)
|
||
TableTraceRoute(fDistance, pVehicles[1]); // doskanowanie dalszego odcinka
|
||
}
|
||
};
|
||
|
||
TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc)
|
||
{ // ustalenie parametr<74>w, zwraca typ komendy, je<6A>li sygna<6E> podaje pr<70>dko<6B><6F> do jazdy
|
||
// fVelDes - pr<70>dko<6B><6F> zadana
|
||
// fDist - dystans w jakim nale<6C>y rozwa<77>y<EFBFBD> ruch
|
||
// fNext - pr<70>dko<6B><6F> na ko<6B>cu tego dystansu
|
||
// fAcc - zalecane przyspieszenie w chwili obecnej - kryterium wyboru dystansu
|
||
double a; // przyspieszenie
|
||
double v; // pr<70>dko<6B><6F>
|
||
double d; // droga
|
||
double d_to_next_sem = 10000.0; //ustaiwamy na pewno dalej ni<6E> widzi AI
|
||
TCommandType go = cm_Unknown;
|
||
eSignNext = NULL;
|
||
int i, k = iLast - iFirst + 1;
|
||
if (k < 0)
|
||
k += iSpeedTableSize; // ilo<6C><6F> pozycji do przeanalizowania
|
||
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<72>w od (iFirst) do (iLast), o ile s<> istotne
|
||
if (sSpeedTable[i].iFlags & spEnabled) // badanie istotno<6E>ci
|
||
{ // o ile dana pozycja tabelki jest istotna
|
||
if (sSpeedTable[i].iFlags & spPassengerStopPoint)
|
||
{ // je<6A>li przystanek, trzeba obs<62>u<EFBFBD>y<EFBFBD> wg rozk<7A>adu
|
||
if (sSpeedTable[i].evEvent->CommandGet() != asNextStop)
|
||
{ // je<6A>li nazwa nie jest zgodna
|
||
if (sSpeedTable[i].fDist < -fLength) // je<6A>li zosta<74> przejechany
|
||
sSpeedTable[i].iFlags =
|
||
0; // to mo<6D>na usun<75><6E> (nie mog<6F> by<62> usuwane w skanowaniu)
|
||
continue; // ignorowanie jakby nie by<62>o tej pozycji
|
||
}
|
||
else if (iDrivigFlags &
|
||
moveStopPoint) // je<6A>li pomijanie W4, to nie sprawdza czasu odjazdu
|
||
{ // tylko gdy nazwa zatrzymania si<73> zgadza
|
||
if (!TrainParams->IsStop())
|
||
{ // je<6A>li nie ma tu postoju
|
||
sSpeedTable[i].fVelNext = -1; // maksymalna pr<70>dko<6B><6F> w tym miejscu
|
||
if (sSpeedTable[i].fDist <
|
||
200.0) // przy 160km/h jedzie 44m/s, to da dok<6F>adno<6E><6F> rz<72>du 5 sekund
|
||
{ // zaliczamy posterunek w pewnej odleg<65>o<EFBFBD>ci przed (cho<68> W4 nie zas<61>ania
|
||
// ju<6A> semafora)
|
||
#if LOGSTOPS
|
||
WriteLog(pVehicle->asName + " as " + TrainParams->TrainName + ": at " +
|
||
to_string(GlobalTime->hh) + ":" + to_string(GlobalTime->mm) +
|
||
" skipped " + asNextStop); // informacja
|
||
#endif
|
||
fLastStopExpDist = mvOccupied->DistCounter + 0.250 +
|
||
0.001 * fLength; // przy jakim dystansie (stanie
|
||
// licznika) ma przesun<75><6E> na
|
||
// nast<73>pny post<73>j
|
||
TrainParams->UpdateMTable(
|
||
GlobalTime->hh, GlobalTime->mm,
|
||
asNextStop.substr(19, asNextStop.length()));
|
||
TrainParams->StationIndexInc(); // przej<65>cie do nast<73>pnej
|
||
asNextStop =
|
||
TrainParams->NextStop(); // pobranie kolejnego miejsca zatrzymania
|
||
// TableClear(); //aby od nowa sprawdzi<7A>o W4 z inn<6E> nazw<7A> ju<6A> - to nie
|
||
// jest dobry pomys<79>
|
||
sSpeedTable[i].iFlags = 0; // nie liczy si<73> ju<6A>
|
||
sSpeedTable[i].fVelNext = -1; // jecha<68>
|
||
continue; // nie analizowa<77> pr<70>dko<6B>ci
|
||
}
|
||
} // koniec obs<62>ugi przelotu na W4
|
||
else
|
||
{ // zatrzymanie na W4
|
||
if (!eSignNext) //je<6A>li nie widzi nast<73>pnego sygna<6E>u
|
||
eSignNext = sSpeedTable[i].evEvent; //ustawia dotychczasow<6F>
|
||
if (mvOccupied->Vel > 0.3) // je<6A>li jedzie (nie trzeba czeka<6B>, a<> si<73>
|
||
// drgania wyt<79>umi<6D> - drzwi zamykane od 1.0)
|
||
sSpeedTable[i].fVelNext = 0; // to b<>dzie zatrzymanie
|
||
// else if
|
||
// ((iDrivigFlags&moveStopCloser)?sSpeedTable[i].fDist<=fMaxProximityDist*(AIControllFlag?1.0:10.0):true)
|
||
else if ((iDrivigFlags & moveStopCloser) ?
|
||
sSpeedTable[i].fDist + fLength <=
|
||
Max0R(sSpeedTable[i].evEvent->ValueGet(2),
|
||
fMaxProximityDist + fLength) :
|
||
sSpeedTable[i].fDist < d_to_next_sem)
|
||
// Ra 2F1I: odleg<65>o<EFBFBD><6F> plus d<>ugo<67><6F> poci<63>gu musi by<62> mniejsza od d<>ugo<67>ci
|
||
// peronu, chyba <20>e poci<63>g jest d<>u<EFBFBD>szy, to wtedy minimalna
|
||
// je<6A>li d<>ugo<67><6F> peronu ((sSpeedTable[i].evEvent->ValueGet(2)) nie podana,
|
||
// przyj<79><6A> odleg<65>o<EFBFBD><6F> fMinProximityDist
|
||
{ // je<6A>li si<73> zatrzyma<6D> przy W4, albo sta<74> w momencie zobaczenia W4
|
||
if (!AIControllFlag) // AI tylko sobie otwiera drzwi
|
||
iDrivigFlags &= ~moveStopCloser; // w razie prze<7A><65>czenia na AI ma
|
||
// nie podci<63>ga<67> do W4, gdy
|
||
// u<>ytkownik zatrzyma<6D> za daleko
|
||
if ((iDrivigFlags & moveDoorOpened) == 0)
|
||
{ // drzwi otwiera<72> jednorazowo
|
||
iDrivigFlags |= moveDoorOpened; // nie wykonywa<77> drugi raz
|
||
if (mvOccupied->DoorOpenCtrl == 1) //(mvOccupied->TrainType==dt_EZT)
|
||
{ // otwieranie drzwi w EZT
|
||
if (AIControllFlag) // tylko AI otwiera drzwi EZT, u<>ytkownik
|
||
// musi samodzielnie
|
||
if (!mvOccupied->DoorLeftOpened &&
|
||
!mvOccupied->DoorRightOpened)
|
||
{ // otwieranie drzwi
|
||
int p2 =
|
||
int(floor(sSpeedTable[i].evEvent->ValueGet(2))) %
|
||
10; // p7=platform side (1:left, 2:right, 3:both)
|
||
int lewe = (iDirection > 0) ? 1 : 2; // je<6A>li jedzie do
|
||
// ty<74>u, to drzwi
|
||
// otwiera
|
||
// odwrotnie
|
||
int prawe = (iDirection > 0) ? 2 : 1;
|
||
if (p2 & lewe)
|
||
mvOccupied->DoorLeft(true);
|
||
if (p2 & prawe)
|
||
mvOccupied->DoorRight(true);
|
||
// if (p2&3) //<2F>eby jeszcze poczeka<6B> chwil<69>, zanim
|
||
// zamknie
|
||
// WaitingSet(10); //10 sekund (wzi<7A><69> z rozk<7A>adu????)
|
||
}
|
||
}
|
||
else
|
||
{ // otwieranie drzwi w sk<73>adach wagonowych - docelowo wysy<73>a<EFBFBD>
|
||
// komend<6E> zezwolenia na otwarcie drzwi
|
||
int p7, lewe,
|
||
prawe; // p7=platform side (1:left, 2:right, 3:both)
|
||
p7 = int(floor(sSpeedTable[i].evEvent->ValueGet(2))) %
|
||
10; // tu b<>dzie jeszcze d<>ugo<67><6F> peronu zaokr<6B>glona do 10m
|
||
// (20m bezpieczniej, bo nie modyfikuje bitu 1)
|
||
TDynamicObject *p = pVehicles[0]; // pojazd na czole sk<73>adu
|
||
while (p)
|
||
{ // otwieranie drzwi w pojazdach - flaga zezwolenia by<62>a by
|
||
// lepsza
|
||
lewe = (p->DirectionGet() > 0) ? 1 : 2; // je<6A>li jedzie do
|
||
// ty<74>u, to drzwi
|
||
// otwiera odwrotnie
|
||
prawe = 3 - lewe;
|
||
p->MoverParameters->BatterySwitch(true); // wagony musz<73>
|
||
// mie<69> bateri<72>
|
||
// za<7A><61>czon<6F> do
|
||
// otwarcia
|
||
// drzwi...
|
||
if (p7 & lewe)
|
||
p->MoverParameters->DoorLeft(true);
|
||
if (p7 & prawe)
|
||
p->MoverParameters->DoorRight(true);
|
||
p = p->Next(); // pojazd pod<6F><64>czony z ty<74>u (patrz<72>c od
|
||
// czo<7A>a)
|
||
}
|
||
// if (p7&3) //<2F>eby jeszcze poczeka<6B> chwil<69>, zanim zamknie
|
||
// WaitingSet(10); //10 sekund (wzi<7A><69> z rozk<7A>adu????)
|
||
}
|
||
if (fStopTime >
|
||
-5) // na ko<6B>cu rozk<7A>adu si<73> ustawia 60s i tu by by<62>o skr<6B>cenie
|
||
WaitingSet(10); // 10 sekund (wzi<7A><69> z rozk<7A>adu????) - czekanie
|
||
// niezale<6C>ne od sposobu obs<62>ugi drzwi, bo
|
||
// op<6F><70>nia r<>wnie<69> kierownika
|
||
}
|
||
if (TrainParams->UpdateMTable(
|
||
GlobalTime->hh, GlobalTime->mm,
|
||
asNextStop.substr(20, asNextStop.length())))
|
||
{ // to si<73> wykona tylko raz po zatrzymaniu na W4
|
||
if (TrainParams->CheckTrainLatency() < 0.0)
|
||
iDrivigFlags |= moveLate; // odnotowano sp<73><70>nienie
|
||
else
|
||
iDrivigFlags &= ~moveLate; // przyjazd o czasie
|
||
if (TrainParams->DirectionChange()) // je<6A>li "@" w rozk<7A>adzie, to
|
||
// wykonanie dalszych komend
|
||
{ // wykonanie kolejnej komendy, nie dotyczy ostatniej stacji
|
||
if (iDrivigFlags & movePushPull) // SN61 ma si<73> te<74> nie rusza<7A>,
|
||
// chyba <20>e ma wagony
|
||
{
|
||
iDrivigFlags |= moveStopHere; // EZT ma sta<74> przy peronie
|
||
if (OrderNextGet() != Change_direction)
|
||
{
|
||
OrderPush(Change_direction); // zmiana kierunku
|
||
OrderPush(TrainParams->StationIndex <
|
||
TrainParams->StationCount ?
|
||
Obey_train :
|
||
Shunt); // to dalej wg rozk<7A>adu
|
||
}
|
||
}
|
||
else // a dla lokomotyw...
|
||
iDrivigFlags &=
|
||
~(moveStopPoint | moveStopHere); // pozwolenie na
|
||
// przejechanie za W4
|
||
// przed czasem i nie
|
||
// ma sta<74>
|
||
JumpToNextOrder(); // przej<65>cie do kolejnego rozkazu (zmiana
|
||
// kierunku, odczepianie)
|
||
iDrivigFlags &= ~moveStopCloser; // ma nie podje<6A>d<EFBFBD>a<EFBFBD> pod W4 po
|
||
// przeciwnej stronie
|
||
sSpeedTable[i].iFlags = 0; // ten W4 nie liczy si<73> ju<6A> zupe<70>nie
|
||
// (nie wy<77>le SetVelocity)
|
||
sSpeedTable[i].fVelNext = -1; // jecha<68>
|
||
continue; // nie analizowa<77> pr<70>dko<6B>ci
|
||
}
|
||
}
|
||
if (OrderCurrentGet() == Shunt)
|
||
{
|
||
OrderNext(Obey_train); // uruchomi<6D> jazd<7A> poci<63>gow<6F>
|
||
CheckVehicles(); // zmieni<6E> <20>wiat<61>a
|
||
}
|
||
if (TrainParams->StationIndex < TrainParams->StationCount)
|
||
{ // je<6A>li s<> dalsze stacje, czekamy do godziny odjazdu
|
||
|
||
if (TrainParams->IsTimeToGo(GlobalTime->hh, GlobalTime->mm))
|
||
{ // z dalsz<73> akcj<63> czekamy do godziny odjazdu
|
||
if (TrainParams->CheckTrainLatency() < 0)
|
||
WaitingSet(20); //Jak sp<73><70>niony to czeka 20s
|
||
// iDrivigFlags|=moveLate1; //oflagowa<77>, gdy odjazd ze
|
||
// sp<73><70>nieniem, b<>dzie jecha<68> forsowniej
|
||
fLastStopExpDist =
|
||
mvOccupied->DistCounter + 0.050 +
|
||
0.001 * fLength; // przy jakim dystansie (stanie licznika)
|
||
// ma przesun<75><6E> na nast<73>pny post<73>j
|
||
// Controlled-> //zapisa<73> odleg<65>o<EFBFBD><6F> do przejechania
|
||
TrainParams->StationIndexInc(); // przej<65>cie do nast<73>pnej
|
||
asNextStop = TrainParams->NextStop(); // pobranie kolejnego miejsca zatrzymania
|
||
// TableClear(); //aby od nowa sprawdzi<7A>o W4 z inn<6E> nazw<7A> ju<6A> - to nie jest dobry pomys<79>
|
||
#if LOGSTOPS
|
||
WriteLog(pVehicle->asName + " as " + TrainParams->TrainName +
|
||
": at " + to_string(GlobalTime->hh) + ":" +
|
||
to_string(GlobalTime->mm) + " next " +
|
||
asNextStop); // informacja
|
||
#endif
|
||
if (int(floor(sSpeedTable[i].evEvent->ValueGet(1))) & 1)
|
||
iDrivigFlags |= moveStopHere; // nie podje<6A>d<EFBFBD>a<EFBFBD> do semafora,
|
||
// je<6A>li droga nie jest wolna
|
||
else
|
||
iDrivigFlags &= ~moveStopHere; //po czasie jed<65> dalej
|
||
iDrivigFlags |= moveStopCloser; // do nast<73>pnego W4 podjecha<68>
|
||
// blisko (z doci<63>ganiem)
|
||
iDrivigFlags &= ~moveStartHorn; // bez tr<74>bienia przed odjazdem
|
||
sSpeedTable[i].iFlags =
|
||
0; // nie liczy si<73> ju<6A> zupe<70>nie (nie wy<77>le SetVelocity)
|
||
sSpeedTable[i].fVelNext = -1; // mo<6D>na jecha<68> za W4
|
||
if (go == cm_Unknown) // je<6A>li nie by<62>o komendy wcze<7A>niej
|
||
go = cm_Ready; // got<6F>w do odjazdu z W4 (semafor mo<6D>e
|
||
// zatrzyma<6D>)
|
||
if (tsGuardSignal) // je<6A>li mamy g<>os kierownika, to odegra<72>
|
||
iDrivigFlags |= moveGuardSignal;
|
||
continue; // nie analizowa<77> pr<70>dko<6B>ci
|
||
} // koniec startu z zatrzymania
|
||
} // koniec obs<62>ugi pocz<63>tkowych stacji
|
||
else
|
||
{ // je<6A>li dojechali<6C>my do ko<6B>ca rozk<7A>adu
|
||
#if LOGSTOPS
|
||
WriteLog(pVehicle->asName + " as " + TrainParams->TrainName +
|
||
": at " + to_string(GlobalTime->hh) + ":" +
|
||
to_string(GlobalTime->mm) +
|
||
" end of route."); // informacja
|
||
#endif
|
||
asNextStop = TrainParams->NextStop(); // informacja o ko<6B>cu trasy
|
||
TrainParams->NewName("none"); // czyszczenie nieaktualnego rozk<7A>adu
|
||
// TableClear(); //aby od nowa sprawdzi<7A>o W4 z inn<6E> nazw<7A> ju<6A> - to
|
||
// nie jest dobry pomys<79>
|
||
iDrivigFlags &=
|
||
~(moveStopCloser |
|
||
moveStopPoint); // ma nie podje<6A>d<EFBFBD>a<EFBFBD> pod W4 i ma je pomija<6A>
|
||
sSpeedTable[i].iFlags =
|
||
0; // W4 nie liczy si<73> ju<6A> (nie wy<77>le SetVelocity)
|
||
sSpeedTable[i].fVelNext = -1; // mo<6D>na jecha<68> za W4
|
||
fLastStopExpDist = -1.0f; // nie ma rozk<7A>adu, nie ma usuwania stacji
|
||
WaitingSet(60); // tak ze 2 minuty, a<> wszyscy wysi<73>d<EFBFBD>
|
||
JumpToNextOrder(); // wykonanie kolejnego rozkazu (Change_direction
|
||
// albo Shunt)
|
||
iDrivigFlags |= moveStopHere | moveStartHorn; // ma si<73> nie rusza<7A>
|
||
// a<> do momentu
|
||
// podania sygna<6E>u
|
||
continue; // nie analizowa<77> pr<70>dko<6B>ci
|
||
} // koniec obs<62>ugi ostatniej stacji
|
||
} // if (MoverParameters->Vel==0.0)
|
||
} // koniec obs<62>ugi zatrzymania na W4
|
||
} // koniec warunku pomijania W4 podczas zmiany czo<7A>a
|
||
else
|
||
{ // skoro pomijanie, to jecha<68> i ignorowa<77> W4
|
||
sSpeedTable[i].iFlags = 0; // W4 nie liczy si<73> ju<6A> (nie zatrzymuje jazdy)
|
||
sSpeedTable[i].fVelNext = -1;
|
||
continue; // nie analizowa<77> pr<70>dko<6B>ci
|
||
}
|
||
} // koniec obs<62>ugi W4
|
||
v = sSpeedTable[i].fVelNext; // odczyt pr<70>dko<6B>ci do zmiennej pomocniczej
|
||
if (sSpeedTable[i].iFlags &
|
||
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 & spEvent) // W4 mo<6D>e si<73> deaktywowa<77>
|
||
{ // je<6A>eli event, mo<6D>e by<62> potrzeba wys<79>ania komendy, aby ruszy<7A>
|
||
// sprawdzanie event<6E>w pasywnych mini<6E>tych
|
||
if (sSpeedTable[i].fDist < 0.0 && sSemNext == &sSpeedTable[i])
|
||
{
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("TableUpdate: semaphor " + sSemNext->GetName() + " passed by " + OwnerName());
|
||
sSemNext = NULL; // je<6A>li min<69>li<6C>my semafor od ograniczenia to go kasujemy ze
|
||
// zmiennej sprawdzaj<61>cej dla skanowania w prz<72>d
|
||
}
|
||
if (sSpeedTable[i].fDist < 0.0 && sSemNextStop == &sSpeedTable[i])
|
||
{
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("TableUpdate: semaphor " + sSemNextStop->GetName() + " passed by " + OwnerName());
|
||
sSemNextStop = NULL; // je<6A>li min<69>li<6C>my semafor od ograniczenia to go kasujemy ze
|
||
// zmiennej sprawdzaj<61>cej dla skanowania w prz<72>d
|
||
}
|
||
if (sSpeedTable[i].fDist > 0.0 &&
|
||
sSpeedTable[i].IsProperSemaphor(OrderCurrentGet()))
|
||
{
|
||
if (!sSemNext)
|
||
{
|
||
sSemNext = &sSpeedTable[i]; // je<6A>li jest mieni<6E>ty poprzedni
|
||
// semafor a wcze<7A>niej
|
||
// byl nowy to go dorzucamy do zmiennej, <20>eby ca<63>y
|
||
// czas widzia<69> najbli<6C>szy
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("TableUpdate: Next semaphor: " + sSemNext->GetName() + " by " + OwnerName());
|
||
}
|
||
if (!sSemNextStop || (sSemNextStop && sSemNextStop->fVelNext != 0 &&
|
||
sSpeedTable[i].fVelNext == 0))
|
||
sSemNextStop = &sSpeedTable[i];
|
||
}
|
||
if (sSpeedTable[i].iFlags & spOutsideStation)
|
||
{ // je<6A>li W5, to reakcja zale<6C>na od trybu jazdy
|
||
if (OrderCurrentGet() & Obey_train)
|
||
{ // w trybie poci<63>gowym: mo<6D>na przyspieszy<7A> do wskazanej pr<70>dko<6B>ci (po
|
||
// zjechaniu z rozjazd<7A>w)
|
||
v = -1.0; // ignorowa<77>?
|
||
//TODO trzeba zmieni<6E> przypisywanie VelSignal na VelSignalLast
|
||
if (sSpeedTable[i].fDist < 0.0) // je<6A>li wska<6B>nik zosta<74> mini<6E>ty
|
||
{
|
||
VelSignalLast = v; //ustawienie pr<70>dko<6B>ci na -1
|
||
// iStationStart=TrainParams->StationIndex; //zaktualizowa<77>
|
||
// wy<77>wietlanie rozk<7A>adu
|
||
}
|
||
else if (!(iDrivigFlags & moveSwitchFound)) // je<6A>li rozjazdy ju<6A> mini<6E>te
|
||
VelSignalLast = v; //!!! to te<74> koniec ograniczenia
|
||
}
|
||
else
|
||
{ // w trybie manewrowym: skanowa<77> od niego wstecz, stan<61><6E> po wyjechaniu za
|
||
// sygnalizator i zmieni<6E> kierunek
|
||
v = 0.0; // zmiana kierunku mo<6D>e by<62> podanym sygna<6E>em, ale wypada<64>o by
|
||
// zmieni<6E> <20>wiat<61>o wcze<7A>niej
|
||
if (!(iDrivigFlags & moveSwitchFound)) // je<6A>li nie ma rozjazdu
|
||
iDrivigFlags |= moveTrackEnd; // to dalsza jazda trwale ograniczona (W5,
|
||
// koniec toru)
|
||
}
|
||
}
|
||
else if (sSpeedTable[i].iFlags & spStopOnSBL)
|
||
{ // je<6A>li S1 na SBL
|
||
if (mvOccupied->Vel < 2.0) // stan<61><6E> nie musi, ale zwolni<6E> przynajmniej
|
||
if (sSpeedTable[i].fDist < fMaxProximityDist) // jest w maksymalnym zasi<73>gu
|
||
{
|
||
eSignSkip = sSpeedTable[i]
|
||
.evEvent; // to mo<6D>na go pomin<69><6E> (wzi<7A><69> drug<75> pr<70>dkos<6F>)
|
||
iDrivigFlags |= moveVisibility; // jazda na widoczno<6E><6F> - skanowa<77>
|
||
// mo<6D>liwo<77><6F> kolizji i nie podje<6A>d<EFBFBD>a<EFBFBD>
|
||
// zbyt blisko
|
||
// usun<75><6E> flag<61> po podjechaniu blisko semafora zezwalaj<61>cego na jazd<7A>
|
||
// ostro<72>nie interpretowa<77> sygna<6E>y - semafor mo<6D>e zezwala<6C> na jazd<7A>
|
||
// poci<63>gu z przodu!
|
||
}
|
||
if (eSignSkip != sSpeedTable[i].evEvent) // je<6A>li ten SBL nie jest do pomini<6E>cia
|
||
// TODO sprawdzi<7A> do kt<6B>rej zmiennej jest przypisywane v i zmieni<6E> to tutaj
|
||
v = sSpeedTable[i].evEvent->ValueGet(1); // to ma 0 odczytywa<77>
|
||
}
|
||
else if (sSpeedTable[i].IsProperSemaphor(OrderCurrentGet()))
|
||
{ // to semaphor
|
||
if (sSpeedTable[i].fDist < 0)
|
||
VelSignalLast = sSpeedTable[i].fVelNext; //mini<6E>ty daje pr<70>dko<6B><6F> obowi<77>zuj<75>c<EFBFBD>
|
||
else
|
||
{
|
||
iDrivigFlags |= moveSemaphorFound; //je<6A>li z przodu to dajemy falg<6C>, <20>e jest
|
||
d_to_next_sem = Min0R(sSpeedTable[i].fDist, d_to_next_sem);
|
||
}
|
||
}
|
||
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<7A> inne warunki
|
||
{
|
||
if (sSpeedTable[i].fSectionVelocityDist == 0.0)
|
||
{
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("TableUpdate: Event is behind. SVD = 0: " + sSpeedTable[i].evEvent->asName);
|
||
sSpeedTable[i].iFlags = 0; // je<6A>li punktowy to kasujemy i nie dajemy ograniczenia na sta<74>e
|
||
}
|
||
else if (sSpeedTable[i].fSectionVelocityDist < 0.0)
|
||
{ // ograniczenie obowi<77>zuj<75>ce do nast<73>pnego
|
||
if (sSpeedTable[i].fVelNext == Global::Min0RSpeed(sSpeedTable[i].fVelNext, VelLimitLast) &&
|
||
sSpeedTable[i].fVelNext != VelLimitLast)
|
||
{ // je<6A>li ograniczenie jest mniejsze ni<6E> obecne to obowi<77>zuje od zaraz
|
||
VelLimitLast = sSpeedTable[i].fVelNext;
|
||
}
|
||
else if (sSpeedTable[i].fDist < -fLength)
|
||
{ // je<6A>li wi<77>ksze to musi wyjecha<68> za poprzednie
|
||
VelLimitLast = sSpeedTable[i].fVelNext;
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("TableUpdate: Event is behind. SVD < 0: " + sSpeedTable[i].evEvent->asName);
|
||
sSpeedTable[i].iFlags = 0; // wyjechali<6C>my poza poprzednie, mo<6D>na skasowa<77>
|
||
}
|
||
}
|
||
else
|
||
{ // je<6A>li wi<77>ksze to ograniczenie ma swoj<6F> d<>ugo<67><6F>
|
||
if (sSpeedTable[i].fVelNext == Global::Min0RSpeed(sSpeedTable[i].fVelNext, VelLimitLast) &&
|
||
sSpeedTable[i].fVelNext != VelLimitLast)
|
||
{ // je<6A>li ograniczenie jest mniejsze ni<6E> obecne to obowi<77>zuje od zaraz
|
||
VelLimitLast = sSpeedTable[i].fVelNext;
|
||
}
|
||
else if (sSpeedTable[i].fDist < -fLength && sSpeedTable[i].fVelNext != VelLimitLast)
|
||
{ // je<6A>li wi<77>ksze to musi wyjecha<68> za poprzednie
|
||
VelLimitLast = sSpeedTable[i].fVelNext;
|
||
}
|
||
else if (sSpeedTable[i].fDist < -fLength - sSpeedTable[i].fSectionVelocityDist)
|
||
{ //
|
||
VelLimitLast = -1.0;
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("TableUpdate: Event is behind. SVD > 0: " + sSpeedTable[i].evEvent->asName);
|
||
sSpeedTable[i].iFlags = 0; // wyjechali<6C>my poza poprzednie, mo<6D>na skasowa<77>
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//sprawdzenie event<6E>w pasywnych przed nami
|
||
if ((mvOccupied->CategoryFlag & 1) ?
|
||
sSpeedTable[i].fDist > pVehicles[0]->fTrackBlock - 20.0 :
|
||
false) // jak sygna<6E> jest dalej ni<6E> zawalidroga
|
||
v = 0.0; // to mo<6D>e by<62> podany dla tamtego: jecha<68> tak, jakby tam stop by<62>
|
||
else
|
||
{ // zawalidrogi nie ma (albo pojazd jest samochodem), sprawdzi<7A> sygna<6E>
|
||
if (sSpeedTable[i].iFlags & spShuntSemaphor) // je<6A>li Tm - w zasadzie to sprawdzi<7A>
|
||
// komend<6E>!
|
||
{ // je<6A>li podana pr<70>dko<6B><6F> manewrowa
|
||
if ((OrderCurrentGet() & Obey_train) ? v == 0.0 : false)
|
||
{ // je<6A>li tryb poci<63>gowy a tarcze ma ShuntVelocity 0 0
|
||
v = -1; // ignorowa<77>, chyba <20>e pr<70>dko<6B><6F> stanie si<73> niezerowa
|
||
if (sSpeedTable[i].iFlags & spElapsed) // a jak przejechana
|
||
sSpeedTable[i].iFlags = 0; // to mo<6D>na usun<75><6E>, bo podstawowy automat
|
||
// usuwa tylko niezerowe
|
||
}
|
||
else if (go == cm_Unknown) // je<6A>li jeszcze nie ma komendy
|
||
if (v != 0.0) // komenda jest tylko gdy ma jecha<68>, bo stoi na podstawie
|
||
// tabelki
|
||
{ // je<6A>li nie by<62>o komendy wcze<7A>niej - pierwsza si<73> liczy - ustawianie
|
||
// VelSignal
|
||
go = cm_ShuntVelocity; // w trybie poci<63>gowym tylko je<6A>li w<><77>cza
|
||
// tryb manewrowy (v!=0.0)
|
||
// Ra 2014-06: (VelSignal) nie mo<6D>e by<62> tu ustawiane, bo Tm mo<6D>e by<62>
|
||
// daleko
|
||
// VelSignal=v; //nie do ko<6B>ca tak, to jest druga pr<70>dko<6B><6F>
|
||
if (VelSignal == 0.0)
|
||
VelSignal = v; // aby stoj<6F>cy ruszy<7A>
|
||
if (sSpeedTable[i].fDist < 0.0) // je<6A>li przejechany
|
||
{
|
||
VelSignal = v; //!!! ustawienie, gdy przejechany jest lepsze ni<6E>
|
||
// wcale, ale to jeszcze nie to
|
||
sSpeedTable[i].iFlags =
|
||
0; // to mo<6D>na usun<75><6E> (nie mog<6F> by<62> usuwane w skanowaniu)
|
||
}
|
||
}
|
||
}
|
||
else if (!(sSpeedTable[i].iFlags & spSectionVel)) //je<6A>li jaki<6B> event pasywny ale nie ograniczenie
|
||
if (go == cm_Unknown) // je<6A>li nie by<62>o komendy wcze<7A>niej - pierwsza si<73> liczy
|
||
// - ustawianie VelSignal
|
||
if (v < 0.0 ? true : v >= 1.0) // bo warto<74><6F> 0.1 s<>u<EFBFBD>y do hamowania tylko
|
||
{
|
||
go = cm_SetVelocity; // mo<6D>e odjecha<68>
|
||
// Ra 2014-06: (VelSignal) nie mo<6D>e by<62> tu ustawiane, bo semafor mo<6D>e
|
||
// by<62> daleko
|
||
// VelSignal=v; //nie do ko<6B>ca tak, to jest druga pr<70>dko<6B><6F>; -1 nie
|
||
// wpisywa<77>...
|
||
if (VelSignal == 0.0)
|
||
VelSignal = -1.0; // aby stoj<6F>cy ruszy<7A>
|
||
if (sSpeedTable[i].fDist < 0.0) // je<6A>li przejechany
|
||
{
|
||
if (v != 0 ? VelSignal = -1.0 : VelSignal = 0.0)
|
||
; // ustawienie, gdy przejechany jest lepsze ni<6E>
|
||
// wcale, ale to jeszcze nie to
|
||
if (sSpeedTable[i].iFlags & spEvent) // je<6A>li event
|
||
if ((sSpeedTable[i].evEvent != eSignSkip) ?
|
||
true :
|
||
(sSpeedTable[i].fVelNext != 0.0)) // ale inny ni<6E> ten,
|
||
// na kt<6B>rym mini<6E>to
|
||
// S1, chyba <20>e si<73>
|
||
// ju<6A> zmieni<6E>o
|
||
iDrivigFlags &= ~moveVisibility; // sygna<6E> zezwalaj<61>cy na
|
||
// jazd<7A> wy<77><79>cza jazd<7A> na
|
||
// widoczno<6E><6F> (S1 na SBL)
|
||
|
||
// usun<75><6E> je<6A>li nie jest ograniczeniem pr<70>dko<6B>ci
|
||
sSpeedTable[i].iFlags =
|
||
0; // to mo<6D>na usun<75><6E> (nie mog<6F> by<62> usuwane w skanowaniu)
|
||
}
|
||
}
|
||
else if (sSpeedTable[i].evEvent->StopCommand())
|
||
{ // je<6A>li pr<70>dko<6B><6F> jest zerowa, a kom<6F>rka zawiera komend<6E>
|
||
eSignNext = sSpeedTable[i].evEvent; // dla informacji
|
||
if (iDrivigFlags &
|
||
moveStopHere) // je<6A>li ma sta<74>, dostaje komend<6E> od razu
|
||
go = cm_Command; // komenda z kom<6F>rki, do wykonania po zatrzymaniu
|
||
else if (sSpeedTable[i].fDist <= 20.0) // je<6A>li ma doci<63>gn<67><6E>, to niech
|
||
// doci<63>ga (moveStopCloser
|
||
// dotyczy doci<63>gania do W4, nie
|
||
// semafora)
|
||
go = cm_Command; // komenda z kom<6F>rki, do wykonania po zatrzymaniu
|
||
}
|
||
} // je<6A>li nie ma zawalidrogi
|
||
} // je<6A>li event
|
||
if (v >= 0.0)
|
||
{ // pozycje z pr<70>dko<6B>ci<63> -1 mo<6D>na spokojnie pomija<6A>
|
||
d = sSpeedTable[i].fDist;
|
||
if ((sSpeedTable[i].iFlags & spElapsed) ?
|
||
false :
|
||
d > 0.0) // sygna<6E> lub ograniczenie z przodu (+32=przejechane)
|
||
{ // 2014-02: je<6A>li stoi, a ma do przejechania kawa<77>ek, to niech jedzie
|
||
if ((mvOccupied->Vel == 0.0) ?
|
||
((sSpeedTable[i].iFlags &
|
||
(spEnabled | spEvent | spPassengerStopPoint)) ==
|
||
(spEnabled | spEvent | spPassengerStopPoint)) &&
|
||
(d > fMaxProximityDist) :
|
||
false)
|
||
a = (iDrivigFlags & moveStopCloser) ? fAcc : 0.0; // ma podjecha<68> bli<6C>ej -
|
||
// czy na pewno w tym
|
||
// miejscu taki warunek?
|
||
else
|
||
{
|
||
a = (v * v - mvOccupied->Vel * mvOccupied->Vel) /
|
||
(25.92 * d); // przyspieszenie: ujemne, gdy trzeba hamowa<77>
|
||
if (d < fMinProximityDist) // jak jest ju<6A> blisko
|
||
if (v < fVelDes)
|
||
fVelDes = v; // ograniczenie aktualnej pr<70>dko<6B>ci
|
||
}
|
||
}
|
||
else if (sSpeedTable[i].iFlags & spTrack) // je<6A>li tor
|
||
{ // tor ogranicza pr<70>dko<6B><6F>, dop<6F>ki ca<63>y sk<73>ad nie przejedzie,
|
||
// d=fLength+d; //zamiana na d<>ugo<67><6F> liczon<6F> do przodu
|
||
if (v >= 1.0) // EU06 si<73> zawiesza<7A>o po dojechaniu na koniec toru postojowego
|
||
if (d < -fLength)
|
||
continue; // zap<61>tlenie, je<6A>li ju<6A> wyjecha<68> za ten odcinek
|
||
if (v < fVelDes)
|
||
fVelDes =
|
||
v; // ograniczenie aktualnej pr<70>dko<6B>ci a<> do wyjechania za ograniczenie
|
||
// if (v==0.0) fAcc=-0.9; //hamowanie je<6A>li stop
|
||
continue; // i tyle wystarczy
|
||
}
|
||
else // event trzyma tylko je<6A>li VelNext=0, nawet po przejechaniu (nie powinno
|
||
// dotyczy<7A> samochod<6F>w?)
|
||
a = (v == 0.0 ? -1.0 : fAcc); // ruszanie albo hamowanie
|
||
if (a < fAcc && v == Min0R(v, fNext))
|
||
{ // mniejsze przyspieszenie to mniejsza mo<6D>liwo<77><6F> rozp<7A>dzenia si<73> albo konieczno<6E><6F>
|
||
// hamowania
|
||
// je<6A>li droga wolna, to mo<6D>e by<62> a>1.0 i si<73> tu nie za<7A>apuje
|
||
// if (mvOccupied->Vel>10.0)
|
||
fAcc = a; // zalecane przyspieszenie (nie musi by<62> uwzgl<67>dniane przez AI)
|
||
fNext = v; // istotna jest pr<70>dko<6B><6F> na ko<6B>cu tego odcinka
|
||
fDist = d; // dlugo<67><6F> odcinka
|
||
}
|
||
else if ((fAcc > 0) && (v > 0) && (v <= fNext))
|
||
{ // je<6A>li nie ma wskaza<7A> do hamowania, mo<6D>na poda<64> drog<6F> i pr<70>dko<6B><6F> na jej ko<6B>cu
|
||
fNext = v; // istotna jest pr<70>dko<6B><6F> na ko<6B>cu tego odcinka
|
||
fDist = d; // dlugo<67><6F> odcinka (kolejne pozycje mog<6F> wyd<79>u<EFBFBD>a<EFBFBD> drog<6F>, je<6A>li
|
||
// pr<70>dko<6B><6F> jest sta<74>a)
|
||
}
|
||
} // if (v>=0.0)
|
||
if (fNext >= 0.0)
|
||
{ // je<6A>li ograniczenie
|
||
if ((sSpeedTable[i].iFlags & (spEnabled | spEvent)) ==
|
||
(spEnabled | spEvent)) // tylko sygna<6E> przypisujemy
|
||
if (!eSignNext) // je<6A>li jeszcze nic nie zapisane tam
|
||
eSignNext = sSpeedTable[i].evEvent; // dla informacji
|
||
if (fNext == 0.0)
|
||
break; // nie ma sensu analizowa<77> tabelki dalej
|
||
}
|
||
} // if (sSpeedTable[i].iFlags&1)
|
||
} // for
|
||
|
||
if (VelSignalLast >= 0.0 && !(iDrivigFlags & (moveSemaphorFound | moveSwitchFound)) &&
|
||
(OrderCurrentGet() & Obey_train))
|
||
VelSignalLast = -1.0; // je<6A>li mieli<6C>my ograniczenie z semafora i nie ma przed nami
|
||
|
||
if (VelSignalLast >= 0.0) //analiza spisanych z tabelki ogranicze<7A> 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, <20>e mijamy W5
|
||
FirstSemaphorDist = d_to_next_sem; // przepisanie znalezionej wartosci do zmiennej
|
||
return go;
|
||
};
|
||
|
||
void TController::TablePurger()
|
||
{ // odtykacz: usuwa mniej istotne pozycje ze <20>rodka tabelki, aby unikn<6B><6E> zatkania
|
||
//(np. brak ograniczenia pomi<6D>dzy zwrotnicami, usuni<6E>te sygna<6E>y, mini<6E>te odcinki <20>uku)
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("TablePurger: Czyszczenie tableki.");
|
||
int i, j, k = iLast - iFirst; // mo<6D>e by<62> 15 albo 16 pozycji, ostatniej nie ma co sprawdza<7A>
|
||
if (k < 0)
|
||
k += iSpeedTableSize; // ilo<6C><6F> pozycji do przeanalizowania
|
||
for (i = iFirst; k > 0; --k, i = (i + 1) % iSpeedTableSize)
|
||
{ // sprawdzenie rekord<72>w od (iFirst) do (iLast), o ile s<> istotne
|
||
if ((sSpeedTable[i].iFlags & spEnabled) ?
|
||
(sSpeedTable[i].fVelNext < 0) && ((sSpeedTable[i].iFlags & 0xAB) == 0xA3) :
|
||
true)
|
||
{ // je<6A>li jest to mini<6E>ty (0x20) tor (0x03) do liczenia ci<63>ciw (0x80), a nie zwrotnica
|
||
// (0x08)
|
||
for (; k > 0; --k, i = (i + 1) % iSpeedTableSize)
|
||
{
|
||
sSpeedTable[i] = sSpeedTable[(i + 1) % iSpeedTableSize]; // skopiowanie
|
||
if (&sSpeedTable[(i + 1) % iSpeedTableSize] == sSemNext)
|
||
sSemNext = &sSpeedTable[i]; // przeniesienie znacznika o semaforze
|
||
if (&sSpeedTable[(i + 1) % iSpeedTableSize] == sSemNextStop)
|
||
sSemNextStop = &sSpeedTable[i]; // przeniesienie znacznika o semaforze
|
||
}
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("Odtykacz usuwa pozycj<63>");
|
||
iLast = (iLast - 1 + iSpeedTableSize) % iSpeedTableSize; // cofni<6E>cie z zawini<6E>ciem
|
||
return;
|
||
}
|
||
}
|
||
// je<6A>li powy<77>sze odtykane nie pomo<6D>e, mo<6D>na usun<75><6E> co<63> wi<77>cej, albo powi<77>kszy<7A> tabelk<6C>
|
||
TSpeedPos *t = new TSpeedPos[iSpeedTableSize + 16]; // zwi<77>kszenie
|
||
k = iLast - iFirst + 1; // tym razem wszystkie
|
||
if (k < 0)
|
||
k += iSpeedTableSize; // ilo<6C><6F> pozycji do przeanalizowania
|
||
for (j = -1, i = iFirst; k > 0; --k)
|
||
{ // przepisywanie rekord<72>w iFirst..iLast na 0..k
|
||
t[++j] = sSpeedTable[i];
|
||
if (&sSpeedTable[i] == sSemNext)
|
||
sSemNext = &t[j]; // przeniesienie znacznika o semaforze
|
||
if (&sSpeedTable[i] == sSemNextStop)
|
||
sSemNextStop = &t[j]; // przeniesienie znacznika o semaforze
|
||
i = (i + 1) % iSpeedTableSize; // kolejna pozycja mog<6F> by<62> zawini<6E>ta
|
||
}
|
||
iFirst = 0; // teraz b<>dzie od zera
|
||
iLast = j; // ostatnia
|
||
delete[] sSpeedTable; // to ju<6A> nie potrzebne
|
||
sSpeedTable = t; // bo jest nowe
|
||
iSpeedTableSize += 16;
|
||
if (Global::iWriteLogEnabled & 8)
|
||
WriteLog("Tabelka powi<77>kszona do "+AnsiString(iSpeedTableSize)+" pozycji");
|
||
};
|
||
//---------------------------------------------------------------------------
|
||
//---------------------------------------------------------------------------
|
||
//---------------------------------------------------------------------------
|
||
|
||
TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche,
|
||
bool primary // czy ma aktywnie prowadzi<7A>?
|
||
)
|
||
{
|
||
iEngineActive = 0;
|
||
LastUpdatedTime = 0.0;
|
||
ElapsedTime = 0.0;
|
||
// inicjalizacja zmiennych
|
||
Psyche = InitPsyche;
|
||
VelDesired = 0.0; // pr<70>dkos<6F> pocz<63>tkowa
|
||
VelforDriver = -1;
|
||
LastReactionTime = 0.0;
|
||
HelpMeFlag = false;
|
||
// fProximityDist=1; //nie u<>ywane
|
||
ActualProximityDist = 1;
|
||
FirstSemaphorDist = 10000.0;
|
||
vCommandLocation.x = 0;
|
||
vCommandLocation.y = 0;
|
||
vCommandLocation.z = 0;
|
||
VelSignal = 0.0; // normalnie na pocz<63>tku ma sta<74>, no chyba <20>e jedzie
|
||
VelLimit = -1.0; // brak ograniczenia pr<70>dko<6B>ci
|
||
VelNext = 120.0;
|
||
VelLimitLast = -1.0; // ostatnie ograniczenie bez ograniczenia
|
||
VelSignalLast = -1.0; // ostatni semafor te<74> bez ograniczenia
|
||
VelRoad = -1.0; // pr<70>dko<6B><6F> drogowa bez ograniczenia
|
||
AIControllFlag = AI;
|
||
pVehicle = NewControll;
|
||
ControllingSet(); // utworzenie po<70><6F>czenia do sterowanego pojazdu
|
||
pVehicles[0] = pVehicle->GetFirstDynamic(0); // pierwszy w kierunku jazdy (Np. Pc1)
|
||
pVehicles[1] = pVehicle->GetFirstDynamic(1); // ostatni w kierunku jazdy (ko<6B>c<EFBFBD>wki)
|
||
/*
|
||
switch (mvOccupied->CabNo)
|
||
{
|
||
case -1: SendCtrlBroadcast("CabActivisation",1); break;
|
||
case 1: SendCtrlBroadcast("CabActivisation",2); break;
|
||
default: AIControllFlag:=False; //na wszelki wypadek
|
||
}
|
||
*/
|
||
iDirection = 0;
|
||
iDirectionOrder = mvOccupied->CabNo; // 1=do przodu (w kierunku sprz<72>gu 0)
|
||
VehicleName = mvOccupied->Name;
|
||
// TrainParams=NewTrainParams;
|
||
// if (TrainParams)
|
||
// asNextStop=TrainParams->NextStop();
|
||
// else
|
||
TrainParams = new TTrainParameters("none"); // rozk<7A>ad jazdy
|
||
// OrderCommand="";
|
||
// OrderValue=0;
|
||
OrdersClear();
|
||
MaxVelFlag = false;
|
||
MinVelFlag = false; // Ra: to nie jest u<>ywane
|
||
iDriverFailCount = 0;
|
||
Need_TryAgain = false; // true, je<6A>li druga pozycja w elektryku nie za<7A>apa<70>a
|
||
Need_BrakeRelease = true;
|
||
deltalog = 0.05; // 1.0;
|
||
|
||
if (WriteLogFlag)
|
||
{
|
||
mkdir("physicslog\\");
|
||
LogFile.open(string("physicslog\\" + VehicleName + ".dat").c_str(),
|
||
std::ios::in | std::ios::out | std::ios::trunc);
|
||
#if LOGPRESS == 0
|
||
LogFile << string(" Time [s] Velocity [m/s] Acceleration [m/ss] Coupler.Dist[m] "
|
||
"Coupler.Force[N] TractionForce [kN] FrictionForce [kN] "
|
||
"BrakeForce [kN] BrakePress [MPa] PipePress [MPa] "
|
||
"MotorCurrent [A] MCP SCP BCP LBP DmgFlag Command CVal1 CVal2")
|
||
.c_str() << "\r\n";
|
||
#endif
|
||
#if LOGPRESS == 1
|
||
LogFile << string("t\tVel\tAcc\tPP\tVVP\tBP\tBVP\tCVP").c_str() << "\n";
|
||
#endif
|
||
LogFile.flush();
|
||
}
|
||
/*
|
||
if (WriteLogFlag)
|
||
{
|
||
assignfile(AILogFile,VehicleName+".txt");
|
||
rewrite(AILogFile);
|
||
writeln(AILogFile,"AI driver log: started OK");
|
||
close(AILogFile);
|
||
}
|
||
*/
|
||
|
||
// VelMargin=2; //Controlling->Vmax*0.015;
|
||
fWarningDuration = 0.0; // nic do wytr<74>bienia
|
||
WaitingExpireTime = 31.0; // tyle ma czeka<6B>, zanim si<73> ruszy
|
||
WaitingTime = 0.0;
|
||
fMinProximityDist = 30.0; // stawanie mi<6D>dzy 30 a 60 m przed przeszkod<6F>
|
||
fMaxProximityDist = 50.0;
|
||
iVehicleCount = -2; // warto<74><6F> neutralna
|
||
// Prepare2press=false; //bez dociskania
|
||
eStopReason = stopSleep; // na pocz<63>tku <20>pi
|
||
fLength = 0.0;
|
||
fMass = 0.0; //[kg]
|
||
eSignNext = NULL; // sygna<6E> zmieniaj<61>cy pr<70>dko<6B><6F>, do pokazania na [F2]
|
||
sSemNext = NULL; // pierwszy semafor w przebiegu
|
||
sSemNextStop = NULL; // pierwszy semafor z sygna<6E>em st<73>j
|
||
fShuntVelocity = 40; // domy<6D>lna pr<70>dko<6B><6F> manewrowa
|
||
fStopTime = 0.0; // czas postoju przed dalsz<73> jazd<7A> (np. na przystanku)
|
||
iDrivigFlags = moveStopPoint; // podjed<65> do W4 mo<6D>liwie blisko
|
||
iDrivigFlags |= moveStopHere; // nie podje<6A>d<EFBFBD>aj do semafora, je<6A>li droga nie jest wolna
|
||
iDrivigFlags |= moveStartHorn; // podaj sygna<6E> po podaniu wolnej drogi
|
||
if (primary)
|
||
iDrivigFlags |= movePrimary; // aktywnie prowadz<64>ce pojazd
|
||
Ready = false;
|
||
if (mvOccupied->CategoryFlag & 2)
|
||
{ // samochody: na podst. http://www.prawko-kwartnik.info/hamowanie.html
|
||
// fDriverBraking=0.0065; //mno<6E>one przez (v^2+40*v) [km/h] daje prawie drog<6F> hamowania [m]
|
||
fDriverBraking = 0.03; // co<63> nie hamuj<75> te samochody zbyt dobrze
|
||
fDriverDist = 5.0; // 5m - zachowywany odst<73>p przed kolizj<7A>
|
||
fVelPlus = 10.0; // dopuszczalne przekroczenie pr<70>dko<6B>ci na ograniczeniu bez hamowania
|
||
fVelMinus = 2.0; // margines pr<70>dko<6B>ci powoduj<75>cy za<7A><61>czenie nap<61>du
|
||
}
|
||
else
|
||
{ // poci<63>gi i statki
|
||
fDriverBraking = 0.06; // mno<6E>one przez (v^2+40*v) [km/h] daje prawie drog<6F> hamowania [m]
|
||
fDriverDist = 50.0; // 50m - zachowywany odst<73>p przed kolizj<7A>
|
||
fVelPlus = 5.0; // dopuszczalne przekroczenie pr<70>dko<6B>ci na ograniczeniu bez hamowania
|
||
fVelMinus = 5.0; // margines pr<70>dko<6B>ci powoduj<75>cy za<7A><61>czenie nap<61>du
|
||
}
|
||
SetDriverPsyche(); // na ko<6B>cu, bo wymaga ustawienia zmiennych
|
||
AccDesired = AccPreferred;
|
||
fVelMax = -1; // ustalenie pr<70>dko<6B>ci dla sk<73>adu
|
||
fBrakeTime = 0.0; // po jakim czasie przekr<6B>ci<63> hamulec
|
||
iVehicles = 0; // na wszelki wypadek
|
||
iSpeedTableSize = 16;
|
||
sSpeedTable = new TSpeedPos[iSpeedTableSize];
|
||
TableClear();
|
||
iRadioChannel = 1; // numer aktualnego kana<6E>u radiowego
|
||
fActionTime = 0.0;
|
||
eAction = actSleep;
|
||
tsGuardSignal = NULL; // komunikat od kierownika
|
||
iGuardRadio = 0; // nie przez radio
|
||
iStationStart = 0; // nic?
|
||
// fAccThreshold mo<6D>e podlega<67> uczeniu si<73> - hamowanie powinno by<62> rejestrowane, a potem
|
||
// analizowane
|
||
fAccThreshold =
|
||
(mvOccupied->TrainType & dt_EZT) ? -0.6 : -0.2; // pr<70>g op<6F><70>nienia dla zadzia<69>ania hamulca
|
||
fLastStopExpDist = -1.0f;
|
||
iRouteWanted = 3; // powiedzmy, <20>e ma jecha<68> prosto (1=w lewo)
|
||
iCoupler = 0; // sprz<72>g; niezerowy gdy ma by<62> pod<6F><64>czanie; samo pod<6F><64>czanie w trybie Connect
|
||
// (wcze<7A>niej mo<6D>e by<62> np. Prepare_engine)
|
||
fOverhead1 = 3000.0; // informacja o napi<70>ciu w sieci trakcyjnej (0=brak drutu, zatrzymaj!)
|
||
fOverhead2 = -1.0; // informacja o sposobie jazdy (-1=normalnie, 0=bez pr<70>du, >0=z opuszczonym i
|
||
// ograniczeniem pr<70>dko<6B>ci)
|
||
iOverheadZero = 0; // suma bitowa jezdy bezpr<70>dowej, bity ustawiane przez pojazdy z
|
||
// podniesionymi pantografami
|
||
iOverheadDown = 0; // suma bitowa opuszczenia pantograf<61>w, bity ustawiane przez pojazdy z
|
||
// podniesionymi pantografami
|
||
fAccDesiredAv = 0.0; // u<>rednione przyspieszenie z kolejnych przeb<65>ysk<73>w <20>wiadomo<6D>ci, <20>eby
|
||
// ograniczy<7A> migotanie
|
||
fVoltage = 0.0; // u<>rednione napi<70>cie sieci: przy spadku poni<6E>ej warto<74>ci minimalnej op<6F><70>ni<6E>
|
||
// rozruch o losowy czas
|
||
};
|
||
|
||
void TController::CloseLog()
|
||
{
|
||
if (WriteLogFlag)
|
||
{
|
||
LogFile.close();
|
||
// if WriteLogFlag)
|
||
// CloseFile(AILogFile);
|
||
/* append(AIlogFile);
|
||
writeln(AILogFile,ElapsedTime5:2,": QUIT");
|
||
close(AILogFile); */
|
||
}
|
||
};
|
||
|
||
TController::~TController()
|
||
{ // wykopanie mechanika z roboty
|
||
delete tsGuardSignal;
|
||
delete TrainParams;
|
||
delete[] sSpeedTable;
|
||
CloseLog();
|
||
};
|
||
|
||
std::string TController::Order2Str(TOrders Order)
|
||
{ // zamiana kodu rozkazu na opis
|
||
if (Order & Change_direction)
|
||
return "Change_direction"; // mo<6D>e by<62> na<6E>o<EFBFBD>ona na inn<6E> i wtedy ma priorytet
|
||
if (Order == Wait_for_orders)
|
||
return "Wait_for_orders";
|
||
if (Order == Prepare_engine)
|
||
return "Prepare_engine";
|
||
if (Order == Shunt)
|
||
return "Shunt";
|
||
if (Order == Connect)
|
||
return "Connect";
|
||
if (Order == Disconnect)
|
||
return "Disconnect";
|
||
if (Order == Obey_train)
|
||
return "Obey_train";
|
||
if (Order == Release_engine)
|
||
return "Release_engine";
|
||
if (Order == Jump_to_first_order)
|
||
return "Jump_to_first_order";
|
||
/* Ra: wersja ze switch nie dzia<69>a prawid<69>owo (czemu?)
|
||
switch (Order)
|
||
{
|
||
Wait_for_orders: return "Wait_for_orders";
|
||
Prepare_engine: return "Prepare_engine";
|
||
Shunt: return "Shunt";
|
||
Change_direction: return "Change_direction";
|
||
Obey_train: return "Obey_train";
|
||
Release_engine: return "Release_engine";
|
||
Jump_to_first_order: return "Jump_to_first_order";
|
||
}
|
||
*/
|
||
return "Undefined!";
|
||
}
|
||
|
||
std::string TController::OrderCurrent()
|
||
{ // pobranie aktualnego rozkazu celem wy<77>wietlenia
|
||
return to_string(OrderPos) + ". " + Order2Str(OrderList[OrderPos]);
|
||
};
|
||
|
||
void TController::OrdersClear()
|
||
{ // czyszczenie tabeli rozkaz<61>w na starcie albo po doj<6F>ciu do ko<6B>ca
|
||
OrderPos = 0;
|
||
OrderTop = 1; // szczyt stosu rozkaz<61>w
|
||
for (int b = 0; b < maxorders; b++)
|
||
OrderList[b] = Wait_for_orders;
|
||
#if LOGORDERS
|
||
WriteLog("--> OrdersClear");
|
||
#endif
|
||
};
|
||
|
||
void TController::Activation()
|
||
{ // umieszczenie obsady w odpowiednim cz<63>onie, wykonywane wy<77><79>cznie gdy steruje AI
|
||
iDirection = iDirectionOrder; // kierunek (wzgl<67>dem sprz<72>g<EFBFBD>w pojazdu z AI) w<>a<EFBFBD>nie zosta<74>
|
||
// ustalony (zmieniony)
|
||
if (iDirection)
|
||
{ // je<6A>li jest ustalony kierunek
|
||
TDynamicObject *old = pVehicle, *d = pVehicle; // w tym siedzi AI
|
||
TController *drugi; // jakby by<62>y dwa, to zamieni<6E> miejscami, a nie robi<62> wycieku pami<6D>ci
|
||
// poprzez nadpisanie
|
||
int brake = mvOccupied->LocalBrakePos;
|
||
while (mvControlling->MainCtrlPos) // samo zap<61>tlenie DecSpeed() nie wystarcza :/
|
||
DecSpeed(true); // wymuszenie zerowania nastawnika jazdy
|
||
while (mvOccupied->ActiveDir < 0)
|
||
mvOccupied->DirectionForward(); // kierunek na 0
|
||
while (mvOccupied->ActiveDir > 0)
|
||
mvOccupied->DirectionBackward();
|
||
if (TestFlag(d->MoverParameters->Couplers[iDirectionOrder < 0 ? 1 : 0].CouplingFlag,
|
||
ctrain_controll))
|
||
{
|
||
mvControlling->MainSwitch(
|
||
false); // dezaktywacja czuwaka, je<6A>li przej<65>cie do innego cz<63>onu
|
||
mvOccupied->DecLocalBrakeLevel(10); // zwolnienie hamulca w opuszczanym poje<6A>dzie
|
||
// mvOccupied->BrakeLevelSet((mvOccupied->BrakeHandle==FVel6)?4:-2); //odci<63>cie na
|
||
// zaworze maszynisty, FVel6 po drugiej stronie nie luzuje
|
||
mvOccupied->BrakeLevelSet(
|
||
mvOccupied->Handle->GetPos(bh_NP)); // odci<63>cie na zaworze maszynisty
|
||
}
|
||
mvOccupied->ActiveCab = mvOccupied->CabNo; // u<>ytkownik moze zmieni<6E> ActiveCab wychodz<64>c
|
||
mvOccupied->CabDeactivisation(); // tak jest w Train.cpp
|
||
// przej<65>cie AI na drug<75> stron<6F> EN57, ET41 itp.
|
||
while (TestFlag(d->MoverParameters->Couplers[iDirection < 0 ? 1 : 0].CouplingFlag,
|
||
ctrain_controll))
|
||
{ // je<6A>li pojazd z przodu jest ukrotniony, to przechodzimy do niego
|
||
d = iDirection * d->DirectionGet() < 0 ? d->Next() :
|
||
d->Prev(); // przechodzimy do nast<73>pnego cz<63>onu
|
||
if (d)
|
||
{
|
||
drugi = d->Mechanik; // zapami<6D>tanie tego, co ewentualnie tam siedzi, <20>eby w razie
|
||
// dw<64>ch zamieni<6E> miejscami
|
||
d->Mechanik = this; // na razie bilokacja
|
||
d->MoverParameters->SetInternalCommand(
|
||
"", 0, 0); // usuni<6E>cie ewentualnie zalegaj<61>cej komendy (Change_direction?)
|
||
if (d->DirectionGet() != pVehicle->DirectionGet()) // je<6A>li s<> przeciwne do siebie
|
||
iDirection = -iDirection; // to b<>dziemy jecha<68> w drug<75> stron<6F> wzgl<67>dem
|
||
// zasiedzianego pojazdu
|
||
pVehicle->Mechanik = drugi; // wsadzamy tego, co ewentualnie by<62> (podw<64>jna trakcja)
|
||
pVehicle->MoverParameters->CabNo = 0; // wy<77><79>czanie kabin po drodze
|
||
pVehicle->MoverParameters->ActiveCab = 0; // i zaznaczenie, <20>e nie ma tam nikogo
|
||
pVehicle = d; // a mechu ma nowy pojazd (no, cz<63>on)
|
||
}
|
||
else
|
||
break; // jak koniec sk<73>adu, to mechanik dalej nie idzie
|
||
}
|
||
if (pVehicle != old)
|
||
{ // je<6A>li zmieniony zosta<74> pojazd prowadzony
|
||
Global::pWorld->CabChange(old, pVehicle); // ewentualna zmiana kabiny u<>ytkownikowi
|
||
ControllingSet(); // utworzenie po<70><6F>czenia do sterowanego pojazdu (mo<6D>e si<73> zmieni<6E>) -
|
||
// silnikowy dla EZT
|
||
}
|
||
if (mvControlling->EngineType ==
|
||
DieselEngine) // dla 2Ls150 - przed ustawieniem kierunku - mo<6D>na zmieni<6E> tryb pracy
|
||
if (mvControlling->ShuntModeAllow)
|
||
mvControlling->CurrentSwitch(
|
||
(OrderList[OrderPos] & Shunt) ||
|
||
(fMass > 224000.0)); // do tego na wzniesieniu mo<6D>e nie da<64> rady na liniowym
|
||
// Ra: to prze<7A><65>czanie poni<6E>ej jest tu bez sensu
|
||
mvOccupied->ActiveCab =
|
||
iDirection; // aktywacja kabiny w prowadzonym poje<6A>dzie (silnikowy mo<6D>e by<62> odwrotnie?)
|
||
// mvOccupied->CabNo=iDirection;
|
||
// mvOccupied->ActiveDir=0; //<2F>eby sam ustawi<77> kierunek
|
||
mvOccupied->CabActivisation(); // uruchomienie kabin w cz<63>onach
|
||
DirectionForward(true); // nawrotnik do przodu
|
||
if (brake) // hamowanie tylko je<6A>li by<62> wcze<7A>niej zahamowany (bo mo<6D>liwe, <20>e jedzie!)
|
||
mvOccupied->IncLocalBrakeLevel(brake); // zahamuj jak wcze<7A>niej
|
||
CheckVehicles(); // sprawdzenie sk<73>adu, AI zapali <20>wiat<61>a
|
||
TableClear(); // resetowanie tabelki skanowania tor<6F>w
|
||
}
|
||
};
|
||
|
||
void TController::AutoRewident()
|
||
{ // autorewident: nastawianie hamulc<6C>w w sk<73>adzie
|
||
int r = 0, g = 0, p = 0; // ilo<6C>ci wagon<6F>w poszczeg<65>lnych typ<79>w
|
||
TDynamicObject *d = pVehicles[0]; // pojazd na czele sk<73>adu
|
||
// 1. Zebranie informacji o sk<73>adzie poci<63>gu <20> przej<65>cie wzd<7A>u<EFBFBD> sk<73>adu i odczyt parametr<74>w:
|
||
// <20> ilo<6C><6F> wagon<6F>w -> s<> zliczane, wszystkich pojazd<7A>w jest (iVehicles)
|
||
// <20> d<>ugo<67><6F> (jako suma) -> jest w (fLength)
|
||
// <20> masa (jako suma) -> jest w (fMass)
|
||
while (d)
|
||
{ // klasyfikacja pojazd<7A>w wg BrakeDelays i mocy (licznik)
|
||
if (d->MoverParameters->Power <
|
||
1) // - lokomotywa - Power>1 - ale mo<6D>e by<62> nieczynna na ko<6B>cu...
|
||
if (TestFlag(d->MoverParameters->BrakeDelays, bdelay_R))
|
||
++r; // - wagon pospieszny - jest R
|
||
else if (TestFlag(d->MoverParameters->BrakeDelays, bdelay_G))
|
||
++g; // - wagon towarowy - jest G (nie ma R)
|
||
else
|
||
++p; // - wagon osobowy - reszta (bez G i bez R)
|
||
d = d->Next(); // kolejny pojazd, pod<6F><64>czony od ty<74>u (licz<63>c od czo<7A>a)
|
||
}
|
||
// 2. Okre<72>lenie typu poci<63>gu i nastawy:
|
||
int ustaw; //+16 dla pasa<73>erskiego
|
||
if (r + g + p == 0)
|
||
ustaw = 16 + bdelay_R; // lokomotywa luzem (mo<6D>e by<62> wielocz<63>onowa)
|
||
else
|
||
{ // je<6A>li s<> wagony
|
||
ustaw = (g < min(4, r + p) ? 16 : 0);
|
||
if (ustaw) // je<6A>li towarowe < Min(4, pospieszne+osobowe)
|
||
{ // to sk<73>ad pasa<73>erski - nastawianie pasa<73>erskiego
|
||
ustaw += (g && (r < g + p)) ? bdelay_P : bdelay_R;
|
||
// je<6A>eli towarowe>0 oraz pospiesze<=towarowe+osobowe to P (0)
|
||
// inaczej R (2)
|
||
}
|
||
else
|
||
{ // inaczej towarowy - nastawianie towarowego
|
||
if ((fLength < 300.0) && (fMass < 600000.0)) //[kg]
|
||
ustaw |= bdelay_P; // je<6A>eli d<>ugo<67><6F><300 oraz masa<600 to P (0)
|
||
else if ((fLength < 500.0) && (fMass < 1300000.0))
|
||
ustaw |= bdelay_R; // je<6A>eli d<>ugo<67><6F><500 oraz masa<1300 to GP (2)
|
||
else
|
||
ustaw |= bdelay_G; // inaczej G (1)
|
||
}
|
||
// zasadniczo na sieci PKP kilka lat temu na P/GP je<6A>dzi<7A>y tylko kontenerowce o
|
||
// rozk<7A>adowej 90 km/h. Pozosta<74>e je<6A>dzi<7A>y 70 km/h i by<62>y nastawione na G.
|
||
}
|
||
d = pVehicles[0]; // pojazd na czele sk<73>adu
|
||
p = 0; // b<>dziemy tu liczy<7A> wagony od lokomotywy dla nastawy GP
|
||
while (d)
|
||
{ // 3. Nastawianie
|
||
switch (ustaw)
|
||
{
|
||
case bdelay_P: // towarowy P - lokomotywa na G, reszta na P.
|
||
d->MoverParameters->BrakeDelaySwitch(d->MoverParameters->Power > 1 ? bdelay_G :
|
||
bdelay_P);
|
||
break;
|
||
case bdelay_G: // towarowy G - wszystko na G, je<6A>li nie ma to P (powinno si<73> wy<77><79>czy<7A>
|
||
// hamulec)
|
||
d->MoverParameters->BrakeDelaySwitch(
|
||
TestFlag(d->MoverParameters->BrakeDelays, bdelay_G) ? bdelay_G : bdelay_P);
|
||
break;
|
||
case bdelay_R: // towarowy GP - lokomotywa oraz 5 pierwszych pojazd<7A>w przy niej na G, reszta
|
||
// na P
|
||
if (d->MoverParameters->Power > 1)
|
||
{
|
||
d->MoverParameters->BrakeDelaySwitch(bdelay_G);
|
||
p = 0; // a jak b<>dzie druga w <20>rodku?
|
||
}
|
||
else
|
||
d->MoverParameters->BrakeDelaySwitch(++p <= 5 ? bdelay_G : bdelay_P);
|
||
break;
|
||
case 16 + bdelay_R: // pasa<73>erski R - na R, je<6A>li nie ma to P
|
||
d->MoverParameters->BrakeDelaySwitch(
|
||
TestFlag(d->MoverParameters->BrakeDelays, bdelay_R) ? bdelay_R : bdelay_P);
|
||
break;
|
||
case 16 + bdelay_P: // pasa<73>erski P - wszystko na P
|
||
d->MoverParameters->BrakeDelaySwitch(bdelay_P);
|
||
break;
|
||
}
|
||
d = d->Next(); // kolejny pojazd, pod<6F><64>czony od ty<74>u (licz<63>c od czo<7A>a)
|
||
}
|
||
};
|
||
|
||
bool TController::CheckVehicles(TOrders user)
|
||
{ // sprawdzenie stanu posiadanych pojazd<7A>w w sk<73>adzie i zapalenie <20>wiate<74>
|
||
TDynamicObject *p; // roboczy wska<6B>nik na pojazd
|
||
iVehicles = 0; // ilo<6C><6F> pojazd<7A>w w sk<73>adzie
|
||
int d = mvOccupied->DirAbsolute; // kt<6B>ry sprz<72>g jest z przodu
|
||
if (!d) // je<6A>li nie ma ustalonego kierunku
|
||
d = mvOccupied->CabNo; // to jedziemy wg aktualnej kabiny
|
||
iDirection = d; // ustalenie kierunku jazdy (powinno zrobi<62> PrepareEngine?)
|
||
d = d >= 0 ? 0 : 1; // kierunek szukania czo<7A>a (numer sprz<72>gu)
|
||
pVehicles[0] = p = pVehicle->FirstFind(d); // pojazd na czele sk<73>adu
|
||
// liczenie pojazd<7A>w w sk<73>adzie i ustalenie parametr<74>w
|
||
int dir = d = 1 - d; // a dalej b<>dziemy zlicza<7A> od czo<7A>a do ty<74>u
|
||
fLength = 0.0; // d<>ugo<67><6F> sk<73>adu do badania wyjechania za ograniczenie
|
||
fMass = 0.0; // ca<63>kowita masa do liczenia stycznej sk<73>adowej grawitacji
|
||
fVelMax = -1; // ustalenie pr<70>dko<6B>ci dla sk<73>adu
|
||
bool main = true; // czy jest g<><67>wnym steruj<75>cym
|
||
iDrivigFlags |= moveOerlikons; // zak<61>adamy, <20>e s<> same Oerlikony
|
||
// Ra 2014-09: ustawi<77> moveMultiControl, je<6A>li wszystkie s<> w ukrotnieniu (i skrajne maj<61>
|
||
// kabin<69>?)
|
||
while (p)
|
||
{ // sprawdzanie, czy jest g<><67>wnym steruj<75>cym, <20>eby nie by<62>o konfliktu
|
||
if (p->Mechanik) // je<6A>li ma obsad<61>
|
||
if (p->Mechanik != this) // ale chodzi o inny pojazd, ni<6E> aktualnie sprawdzaj<61>cy
|
||
if (p->Mechanik->iDrivigFlags & movePrimary) // a tamten ma priorytet
|
||
if ((iDrivigFlags & movePrimary) && (mvOccupied->DirAbsolute) &&
|
||
(mvOccupied->BrakeCtrlPos >= -1)) // je<6A>li rz<72>dzi i ma kierunek
|
||
p->Mechanik->iDrivigFlags &= ~movePrimary; // dezaktywuje tamtego
|
||
else
|
||
main = false; // nici z rz<72>dzenia
|
||
++iVehicles; // jest jeden pojazd wi<77>cej
|
||
pVehicles[1] = p; // zapami<6D>tanie ostatniego
|
||
fLength += p->MoverParameters->Dim.L; // dodanie d<>ugo<67>ci pojazdu
|
||
fMass += p->MoverParameters->TotalMass; // dodanie masy <20><>cznie z <20>adunkiem
|
||
if (fVelMax < 0 ? true : p->MoverParameters->Vmax < fVelMax)
|
||
fVelMax = p->MoverParameters->Vmax; // ustalenie maksymalnej pr<70>dko<6B>ci dla sk<73>adu
|
||
/* //youBy: bez przesady, to jest proteza, napelniac mozna, a nawet trzeba, ale z umiarem!
|
||
//uwzgl<67>dni<6E> jeszcze wy<77><79>czenie hamulca
|
||
if
|
||
((p->MoverParameters->BrakeSystem!=Pneumatic)&&(p->MoverParameters->BrakeSystem!=ElectroPneumatic))
|
||
iDrivigFlags&=~moveOerlikons; //no jednak nie
|
||
else if (p->MoverParameters->BrakeSubsystem!=Oerlikon)
|
||
iDrivigFlags&=~moveOerlikons; //wtedy te<74> nie */
|
||
p = p->Neightbour(dir); // pojazd pod<6F><64>czony od wskazanej strony
|
||
}
|
||
if (main)
|
||
iDrivigFlags |= movePrimary; // nie znaleziono innego, mo<6D>na si<73> porz<72>dzi<7A>
|
||
/* //tabelka z list<73> pojazd<7A>w jest na razie nie potrzebna
|
||
delete[] pVehicles;
|
||
pVehicles=new TDynamicObject*[iVehicles];
|
||
*/
|
||
ControllingSet(); // ustalenie cz<63>onu do sterowania (mo<6D>e by<62> inny ni<6E> zasiedziany)
|
||
int pantmask = 1;
|
||
if (iDrivigFlags & movePrimary)
|
||
{ // je<6A>li jest aktywnie prowadz<64>cym pojazd, mo<6D>e zrobi<62> w<>asny porz<72>dek
|
||
p = pVehicles[0];
|
||
while (p)
|
||
{
|
||
if (TrainParams)
|
||
if (p->asDestination == "none")
|
||
p->DestinationSet(TrainParams->Relation2,
|
||
TrainParams->TrainName); // relacja docelowa, je<6A>li nie by<62>o
|
||
if (AIControllFlag) // je<6A>li prowadzi komputer
|
||
p->RaLightsSet(0, 0); // gasimy <20>wiat<61>a
|
||
if (p->MoverParameters->EnginePowerSource.SourceType == CurrentCollector)
|
||
{ // je<6A>li pojazd posiada pantograf, to przydzielamy mu mask<73>, kt<6B>r<EFBFBD> b<>dzie informowa<77> o
|
||
// je<6A>dzie bezpr<70>dowej
|
||
p->iOverheadMask = pantmask;
|
||
pantmask << 1; // przesuni<6E>cie bit<69>w, max. 32 pojazdy z pantografami w sk<73>adzie
|
||
}
|
||
d = p->DirectionSet(d ? 1 : -1); // zwraca po<70>o<EFBFBD>enie nast<73>pnego (1=zgodny,0=odwr<77>cony -
|
||
// wzgl<67>dem czo<7A>a sk<73>adu)
|
||
p->fScanDist = 300.0; // odleg<65>o<EFBFBD><6F> skanowania w poszukiwaniu innych pojazd<7A>w
|
||
p->ctOwner = this; // dominator oznacza swoje terytorium
|
||
p = p->Next(); // pojazd pod<6F><64>czony od ty<74>u (licz<63>c od czo<7A>a)
|
||
}
|
||
if (AIControllFlag)
|
||
{ // je<6A>li prowadzi komputer
|
||
if (OrderCurrentGet() == Obey_train) // je<6A>li jazda poci<63>gowa
|
||
{
|
||
Lights(1 + 4 + 16, 2 + 32 + 64); //<2F>wiat<61>a poci<63>gowe (Pc1) i ko<6B>c<EFBFBD>wki (Pc5)
|
||
#if LOGPRESS == 0
|
||
AutoRewident(); // nastawianie hamulca do jazdy poci<63>gowej
|
||
#endif
|
||
}
|
||
else if (OrderCurrentGet() & (Shunt | Connect))
|
||
{
|
||
Lights(16, (pVehicles[1]->MoverParameters->CabNo) ?
|
||
1 :
|
||
0); //<2F>wiat<61>a manewrowe (Tb1) na poje<6A>dzie z nap<61>dem
|
||
if (OrderCurrentGet() & Connect) // je<6A>li <20><>czenie, skanowa<77> dalej
|
||
pVehicles[0]->fScanDist =
|
||
5000.0; // odleg<65>o<EFBFBD><6F> skanowania w poszukiwaniu innych pojazd<7A>w
|
||
}
|
||
else if (OrderCurrentGet() == Disconnect)
|
||
if (mvOccupied->ActiveDir > 0) // jak ma kierunek do przodu
|
||
Lights(16, 0); //<2F>wiat<61>a manewrowe (Tb1) tylko z przodu, aby nie pozostawi<77>
|
||
// odczepionego ze <20>wiat<61>em
|
||
else // jak dociska
|
||
Lights(0, 16); //<2F>wiat<61>a manewrowe (Tb1) tylko z przodu, aby nie pozostawi<77>
|
||
// odczepionego ze <20>wiat<61>em
|
||
}
|
||
else // Ra 2014-02: lepiej tu ni<6E> w p<>tli obs<62>uguj<75>cej komendy, bo tam si<73> zmieni informacja
|
||
// o sk<73>adzie
|
||
switch (user) // gdy cz<63>owiek i gdy nast<73>pi<70>o po<70><6F>cznie albo roz<6F><7A>czenie
|
||
{
|
||
case Change_direction:
|
||
while (OrderCurrentGet() & (Change_direction))
|
||
JumpToNextOrder(); // zmian<61> kierunku te<74> mo<6D>na ola<6C>, ale zmieni<6E> kierunek
|
||
// skanowania!
|
||
break;
|
||
case Connect:
|
||
while (OrderCurrentGet() & (Change_direction))
|
||
JumpToNextOrder(); // zmian<61> kierunku te<74> mo<6D>na ola<6C>, ale zmieni<6E> kierunek
|
||
// skanowania!
|
||
if (OrderCurrentGet() & (Connect))
|
||
{ // je<6A>li mia<69>o by<62> <20><>czenie, zak<61>adamy, <20>e jest dobrze (sprawdzi<7A>?)
|
||
iCoupler = 0; // koniec z doczepianiem
|
||
iDrivigFlags &= ~moveConnect; // zdj<64>cie flagi doczepiania
|
||
JumpToNextOrder(); // wykonanie nast<73>pnej komendy
|
||
if (OrderCurrentGet() & (Change_direction))
|
||
JumpToNextOrder(); // zmian<61> kierunku te<74> mo<6D>na ola<6C>, ale zmieni<6E> kierunek
|
||
// skanowania!
|
||
}
|
||
break;
|
||
case Disconnect:
|
||
while (OrderCurrentGet() & (Change_direction))
|
||
JumpToNextOrder(); // zmian<61> kierunku te<74> mo<6D>na ola<6C>, ale zmieni<6E> kierunek
|
||
// skanowania!
|
||
if (OrderCurrentGet() & (Disconnect))
|
||
{ // wypada<64>o by sprawdzi<7A>, czy odczepiono wagony w odpowiednim miejscu
|
||
// (iVehicleCount)
|
||
JumpToNextOrder(); // wykonanie nast<73>pnej komendy
|
||
if (OrderCurrentGet() & (Change_direction))
|
||
JumpToNextOrder(); // zmian<61> kierunku te<74> mo<6D>na ola<6C>, ale zmieni<6E> kierunek
|
||
// skanowania!
|
||
}
|
||
}
|
||
// Ra 2014-09: tymczasowo prymitywne ustawienie warunku pod k<>tem SN61
|
||
if ((mvOccupied->TrainType == dt_EZT) || (iVehicles == 1))
|
||
iDrivigFlags |= movePushPull; // zmiana czo<7A>a przez zmian<61> kabiny
|
||
else
|
||
iDrivigFlags &= ~movePushPull; // zmiana czo<7A>a przez manewry
|
||
} // blok wykonywany, gdy aktywnie prowadzi
|
||
return true;
|
||
}
|
||
|
||
void TController::Lights(int head, int rear)
|
||
{ // zapalenie <20>wiate<74> w sk<73><6B>dzie
|
||
pVehicles[0]->RaLightsSet(head, -1); // zapalenie przednich w pierwszym
|
||
pVehicles[1]->RaLightsSet(-1, rear); // zapalenie ko<6B>c<EFBFBD>wek w ostatnim
|
||
}
|
||
|
||
void TController::DirectionInitial()
|
||
{ // ustawienie kierunku po wczytaniu trainset (mo<6D>e jecha<68> na wstecznym
|
||
mvOccupied->CabActivisation(); // za<7A><61>czenie rozrz<72>du (wirtualne kabiny)
|
||
if (mvOccupied->Vel > 0.0)
|
||
{ // je<6A>li na starcie jedzie
|
||
iDirection = iDirectionOrder =
|
||
(mvOccupied->V > 0 ? 1 : -1); // pocz<63>tkowa pr<70>dko<6B><6F> wymusza kierunek jazdy
|
||
DirectionForward(mvOccupied->V * mvOccupied->CabNo >= 0.0); // a dalej ustawienie nawrotnika
|
||
}
|
||
CheckVehicles(); // sprawdzenie <20>wiate<74> oraz skrajnych pojazd<7A>w do skanowania
|
||
};
|
||
|
||
int TController::OrderDirectionChange(int newdir, TMoverParameters *Vehicle)
|
||
{ // zmiana kierunku jazdy, niezale<6C>nie od kabiny
|
||
int testd = newdir;
|
||
if (Vehicle->Vel < 0.5)
|
||
{ // je<6A>li prawie stoi, mo<6D>na zmieni<6E> kierunek, musi by<62> wykonane dwukrotnie, bo za pierwszym
|
||
// razem daje na zero
|
||
switch (newdir * Vehicle->CabNo)
|
||
{ // DirectionBackward() i DirectionForward() to zmiany wzgl<67>dem kabiny
|
||
case -1: // if (!Vehicle->DirectionBackward()) testd=0; break;
|
||
DirectionForward(false);
|
||
break;
|
||
case 1: // if (!Vehicle->DirectionForward()) testd=0; break;
|
||
DirectionForward(true);
|
||
break;
|
||
}
|
||
if (testd == 0)
|
||
VelforDriver = -1; // kierunek zosta<74> zmieniony na <20><>dany, mo<6D>na jecha<68>
|
||
}
|
||
else // je<6A>li jedzie
|
||
VelforDriver = 0; // ma si<73> zatrzyma<6D> w celu zmiany kierunku
|
||
if ((Vehicle->ActiveDir == 0) && (VelforDriver < Vehicle->Vel)) // Ra: to jest chyba bez sensu
|
||
IncBrake(); // niech hamuje
|
||
if (Vehicle->ActiveDir == testd * Vehicle->CabNo)
|
||
VelforDriver = -1; // mo<6D>na jecha<68>, bo kierunek jest zgodny z <20><>danym
|
||
if (Vehicle->TrainType == dt_EZT)
|
||
if (Vehicle->ActiveDir > 0)
|
||
// if () //tylko je<6A>li jazda poci<63>gowa (tego nie wiemy w momencie odpalania silnika)
|
||
Vehicle->DirectionForward(); // Ra: z przekazaniem do silnikowego
|
||
return (int)VelforDriver; // zwraca pr<70>dko<6B><6F> mechanika
|
||
}
|
||
|
||
void TController::WaitingSet(double Seconds)
|
||
{ // ustawienie odczekania po zatrzymaniu (ustawienie w trakcie jazdy zatrzyma)
|
||
fStopTime = -Seconds; // ujemna warto<74><6F> oznacza oczekiwanie (potem >=0.0)
|
||
}
|
||
|
||
void TController::SetVelocity(double NewVel, double NewVelNext, TStopReason r)
|
||
{ // ustawienie nowej pr<70>dko<6B>ci
|
||
WaitingTime = -WaitingExpireTime; // przypisujemy -WaitingExpireTime, a potem por<6F>wnujemy z
|
||
// zerem
|
||
MaxVelFlag = False; // Ra: to nie jest u<>ywane
|
||
MinVelFlag = False; // Ra: to nie jest u<>ywane
|
||
/* nie u<>ywane
|
||
if ((NewVel>NewVelNext) //je<6A>li oczekiwana wi<77>ksza ni<6E> nast<73>pna
|
||
|| (NewVel<mvOccupied->Vel)) //albo aktualna jest mniejsza ni<6E> aktualna
|
||
fProximityDist=-800.0; //droga hamowania do zmiany pr<70>dko<6B>ci
|
||
else
|
||
fProximityDist=-300.0; //Ra: ujemne warto<74>ci s<> ignorowane
|
||
*/
|
||
if (NewVel == 0.0) // je<6A>li ma stan<61><6E>
|
||
{
|
||
if (r != stopNone) // a jest pow<6F>d podany
|
||
eStopReason = r; // to zapami<6D>ta<74> nowy pow<6F>d
|
||
}
|
||
else
|
||
{
|
||
eStopReason = stopNone; // podana pr<70>dko<6B><6F>, to nie ma powod<6F>w do stania
|
||
// to ca<63>e poni<6E>ej to warunki zatr<74>bienia przed ruszeniem
|
||
if (OrderList[OrderPos] ?
|
||
OrderList[OrderPos] & (Obey_train | Shunt | Connect | Prepare_engine) :
|
||
true) // je<6A>li jedzie w dowolnym trybie
|
||
if ((mvOccupied->Vel <
|
||
1.0)) // jesli stoi (na razie, bo chyba powinien te<74>, gdy hamuje przed semaforem)
|
||
if (iDrivigFlags & moveStartHorn) // jezeli tr<74>bienie w<><77>czone
|
||
if (!(iDrivigFlags & (moveStartHornDone | moveConnect))) // je<6A>li nie zatr<74>bione
|
||
// i nie jest to moment
|
||
// pod<6F><64>czania sk<73>adu
|
||
if (mvOccupied->CategoryFlag & 1) // tylko poci<63>gi tr<74>bi<62> (unimogi tylko na
|
||
// torach, wi<77>c trzeba raczej sprawdza<7A>
|
||
// tor)
|
||
if ((NewVel >= 1.0) || (NewVel < 0.0)) // o ile pr<70>dko<6B><6F> jest znacz<63>ca
|
||
{ // fWarningDuration=0.3; //czas tr<74>bienia
|
||
// if (AIControllFlag) //jak siedzi krasnoludek, to w<><77>czy tr<74>bienie
|
||
// mvOccupied->WarningSignal=pVehicle->iHornWarning; //wysoko<6B><6F> tonu
|
||
// (2=wysoki)
|
||
// iDrivigFlags|=moveStartHornDone; //nie tr<74>bi<62> a<> do ruszenia
|
||
iDrivigFlags |= moveStartHornNow; // zatr<74>b po odhamowaniu
|
||
}
|
||
}
|
||
VelSignal = NewVel; // pr<70>dko<6B><6F> zezwolona na aktualnym odcinku
|
||
VelNext = NewVelNext; // pr<70>dko<6B><6F> przy nast<73>pnym obiekcie
|
||
}
|
||
|
||
/* //funkcja do niczego nie potrzebna (ew. do przesuni<6E>cia pojazdu o odleg<65>o<EFBFBD><6F> NewDist)
|
||
bool TController::SetProximityVelocity(double NewDist,double NewVelNext)
|
||
{//informacja o pr<70>dko<6B>ci w pewnej odleg<65>o<EFBFBD>ci
|
||
#if 0
|
||
if (NewVelNext==0.0)
|
||
WaitingTime=0.0; //nie trzeba ju<6A> czeka<6B>
|
||
//if ((NewVelNext>=0)&&((VelNext>=0)&&(NewVelNext<VelNext))||(NewVelNext<VelSignal))||(VelNext<0))
|
||
{MaxVelFlag=False; //Ra: to nie jest u<>ywane
|
||
MinVelFlag=False; //Ra: to nie jest u<>ywane
|
||
VelNext=NewVelNext;
|
||
fProximityDist=NewDist; //dodatnie: przeliczy<7A> do punktu; ujemne: wzi<7A><69> dos<6F>ownie
|
||
return true;
|
||
}
|
||
//else return false
|
||
#endif
|
||
}
|
||
*/
|
||
|
||
void TController::SetDriverPsyche()
|
||
{
|
||
// double maxdist=0.5; //skalowanie dystansu od innego pojazdu, zmienic to!!!
|
||
if ((Psyche == Aggressive) && (OrderList[OrderPos] == Obey_train))
|
||
{
|
||
ReactionTime = HardReactionTime; // w zaleznosci od charakteru maszynisty
|
||
// if (pOccupied)
|
||
if (mvOccupied->CategoryFlag & 2)
|
||
{
|
||
WaitingExpireTime = 1; // tyle ma czeka<6B> samoch<63>d, zanim si<73> ruszy
|
||
AccPreferred = 3.0; //[m/ss] agresywny
|
||
}
|
||
else
|
||
{
|
||
WaitingExpireTime = 61; // tyle ma czeka<6B>, zanim si<73> ruszy
|
||
AccPreferred = HardAcceleration; // agresywny
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ReactionTime = EasyReactionTime; // spokojny
|
||
if (mvOccupied->CategoryFlag & 2)
|
||
{
|
||
WaitingExpireTime = 3; // tyle ma czeka<6B> samoch<63>d, zanim si<73> ruszy
|
||
AccPreferred = 2.0; //[m/ss]
|
||
}
|
||
else
|
||
{
|
||
WaitingExpireTime = 65; // tyle ma czeka<6B>, zanim si<73> ruszy
|
||
AccPreferred = EasyAcceleration;
|
||
}
|
||
}
|
||
if (mvControlling && mvOccupied)
|
||
{ // with Controlling do
|
||
if (mvControlling->MainCtrlPos < 3)
|
||
ReactionTime = mvControlling->InitialCtrlDelay + ReactionTime;
|
||
if (mvOccupied->BrakeCtrlPos > 1)
|
||
ReactionTime = 0.5 * ReactionTime;
|
||
/*
|
||
if (mvOccupied->Vel>0.1) //o ile jedziemy
|
||
{//sprawdzenie jazdy na widoczno<6E><6F>
|
||
TCoupling
|
||
*c=pVehicles[0]->MoverParameters->Couplers+(pVehicles[0]->DirectionGet()>0?0:1); //sprz<72>g
|
||
z przodu sk<73>adu
|
||
if (c->Connected) //a mamy co<63> z przodu
|
||
if (c->CouplingFlag==0) //je<6A>li to co<63> jest pod<6F><64>czone sprz<72>giem wirtualnym
|
||
{//wyliczanie optymalnego przyspieszenia do jazdy na widoczno<6E><6F> (Ra: na pewno tutaj?)
|
||
double k=c->Connected->Vel; //pr<70>dko<6B><6F> pojazdu z przodu (zak<61>adaj<61>c, <20>e jedzie w t<>
|
||
sam<61> stron<6F>!!!)
|
||
if (k<=mvOccupied->Vel) //por<6F>wnanie modu<64><75>w pr<70>dko<6B>ci [km/h]
|
||
{if (pVehicles[0]->fTrackBlock<fMaxProximityDist) //por<6F>wnianie z minimaln<6C> odleg<65>o<EFBFBD>ci<63>
|
||
kolizyjn<6A>
|
||
k=-AccPreferred; //hamowanie maksymalne, bo jest za blisko
|
||
else
|
||
{//je<6A>li tamten jedzie szybciej, to nie potrzeba modyfikowa<77> przyspieszenia
|
||
double d=(pVehicles[0]->fTrackBlock-0.5*fabs(mvOccupied->V)-fMaxProximityDist);
|
||
//bezpieczna odleg<65>o<EFBFBD><6F> za poprzednim
|
||
//a=(v2*v2-v1*v1)/(25.92*(d-0.5*v1))
|
||
//(v2*v2-v1*v1)/2 to r<><72>nica energii kinetycznych na jednostk<74> masy
|
||
//je<6A>li v2=50km/h,v1=60km/h,d=200m => k=(192.9-277.8)/(25.92*(200-0.5*16.7)=-0.0171
|
||
[m/s^2]
|
||
//je<6A>li v2=50km/h,v1=60km/h,d=100m => k=(192.9-277.8)/(25.92*(100-0.5*16.7)=-0.0357
|
||
[m/s^2]
|
||
//je<6A>li v2=50km/h,v1=60km/h,d=50m => k=(192.9-277.8)/(25.92*( 50-0.5*16.7)=-0.0786
|
||
[m/s^2]
|
||
//je<6A>li v2=50km/h,v1=60km/h,d=25m => k=(192.9-277.8)/(25.92*( 25-0.5*16.7)=-0.1967
|
||
[m/s^2]
|
||
if (d>0) //bo jak ujemne, to zacznie przyspiesza<7A>, aby si<73> zderzy<7A>
|
||
k=(k*k-mvOccupied->Vel*mvOccupied->Vel)/(25.92*d); //energia kinetyczna dzielona
|
||
przez mas<61> i drog<6F> daje przyspieszenie
|
||
else
|
||
k=0.0; //mo<6D>e lepiej nie przyspiesza<7A> -AccPreferred; //hamowanie
|
||
//WriteLog(pVehicle->asName+" "+AnsiString(k));
|
||
}
|
||
if (d<fBrakeDist) //bo z daleka nie ma co hamowa<77>
|
||
AccPreferred=Min0R(k,AccPreferred);
|
||
}
|
||
}
|
||
}
|
||
*/
|
||
}
|
||
};
|
||
|
||
bool TController::PrepareEngine()
|
||
{ // odpalanie silnika
|
||
bool OK;
|
||
bool voltfront, voltrear;
|
||
voltfront = false;
|
||
voltrear = false;
|
||
LastReactionTime = 0.0;
|
||
ReactionTime = PrepareTime;
|
||
iDrivigFlags |= moveActive; // mo<6D>e skanowa<77> sygna<6E>y i reagowa<77> na komendy
|
||
// with Controlling do
|
||
if (((mvControlling->EnginePowerSource.SourceType ==
|
||
CurrentCollector) /*||(mvOccupied->TrainType==dt_EZT)*/))
|
||
{
|
||
if (mvControlling
|
||
->GetTrainsetVoltage()) // sprawdzanie, czy zasilanie jest mo<6D>e w innym cz<63>onie
|
||
{
|
||
voltfront = true;
|
||
voltrear = true;
|
||
}
|
||
}
|
||
// begin
|
||
// if Couplers[0].Connected<>nil)
|
||
// begin
|
||
// if Couplers[0].Connected^.PantFrontVolt or Couplers[0].Connected^.PantRearVolt)
|
||
// voltfront:=true
|
||
// else
|
||
// voltfront:=false;
|
||
// end
|
||
// else
|
||
// voltfront:=false;
|
||
// if Couplers[1].Connected<>nil)
|
||
// begin
|
||
// if Couplers[1].Connected^.PantFrontVolt or Couplers[1].Connected^.PantRearVolt)
|
||
// voltrear:=true
|
||
// else
|
||
// voltrear:=false;
|
||
// end
|
||
// else
|
||
// voltrear:=false;
|
||
// end
|
||
else
|
||
// if EnginePowerSource.SourceType<>CurrentCollector)
|
||
if (mvOccupied->TrainType != dt_EZT)
|
||
voltfront = true; // Ra 2014-06: to jest wirtualny pr<70>d dla spalinowych???
|
||
if (AIControllFlag) // je<6A>li prowadzi komputer
|
||
{ // cz<63><7A><EFBFBD> wykonawcza dla sterowania przez komputer
|
||
mvOccupied->BatterySwitch(true);
|
||
if (mvControlling->EnginePowerSource.SourceType == CurrentCollector)
|
||
{ // je<6A>li silnikowy jest pantografuj<75>cym
|
||
if (mvControlling->PantPress > 4.3)
|
||
{ // je<6A>eli jest wystarczaj<61>ce ci<63>nienie w pantografach
|
||
if ((!mvControlling->bPantKurek3) ||
|
||
(mvControlling->PantPress <=
|
||
mvControlling->ScndPipePress)) // kurek prze<7A><65>czony albo g<><67>wna ju<6A> pompuje
|
||
mvControlling->PantCompFlag = false; // spr<70><72>ark<72> pantograf<61>w mo<6D>na ju<6A> wy<77><79>czy<7A>
|
||
mvControlling->PantFront(true);
|
||
mvControlling->PantRear(true);
|
||
}
|
||
else if (mvControlling->PantPress < 4.2) //<2F>eby nie za<7A><61>cza<7A> zaraz po przekroczeniu 4.0
|
||
{ // za<7A><61>czenie ma<6D>ej spr<70><72>arki
|
||
mvControlling->bPantKurek3 =
|
||
false; // od<6F><64>czenie zbiornika g<><67>wnego, bo z nim nie da rady napompowa<77>
|
||
mvControlling->PantCompFlag = true; // za<7A><61>czenie spr<70><72>arki pantograf<61>w
|
||
}
|
||
}
|
||
// if (mvOccupied->TrainType==dt_EZT)
|
||
//{//Ra 2014-12: po co to tutaj?
|
||
// mvControlling->PantFront(true);
|
||
// mvControlling->PantRear(true);
|
||
//}
|
||
// if (mvControlling->EngineType==DieselElectric)
|
||
// mvControlling->Battery=true; //Ra: to musi by<62> tak?
|
||
}
|
||
if (mvControlling->PantFrontVolt || mvControlling->PantRearVolt || voltfront || voltrear)
|
||
{ // najpierw ustalamy kierunek, je<6A>li nie zosta<74> ustalony
|
||
if (!iDirection) // je<6A>li nie ma ustalonego kierunku
|
||
if (mvOccupied->V == 0)
|
||
{ // ustalenie kierunku, gdy stoi
|
||
iDirection = mvOccupied->CabNo; // wg wybranej kabiny
|
||
if (!iDirection) // je<6A>li nie ma ustalonego kierunku
|
||
if ((mvControlling->PantFrontVolt != 0.0) ||
|
||
(mvControlling->PantRearVolt != 0.0) || voltfront || voltrear)
|
||
{
|
||
if (mvOccupied->Couplers[1].CouplingFlag ==
|
||
ctrain_virtual) // je<6A>li z ty<74>u nie ma nic
|
||
iDirection = -1; // jazda w kierunku sprz<72>gu 1
|
||
if (mvOccupied->Couplers[0].CouplingFlag ==
|
||
ctrain_virtual) // je<6A>li z przodu nie ma nic
|
||
iDirection = 1; // jazda w kierunku sprz<72>gu 0
|
||
}
|
||
}
|
||
else // ustalenie kierunku, gdy jedzie
|
||
if ((mvControlling->PantFrontVolt != 0.0) || (mvControlling->PantRearVolt != 0.0) ||
|
||
voltfront || voltrear)
|
||
if (mvOccupied->V < 0) // jedzie do ty<74>u
|
||
iDirection = -1; // jazda w kierunku sprz<72>gu 1
|
||
else // jak nie do ty<74>u, to do przodu
|
||
iDirection = 1; // jazda w kierunku sprz<72>gu 0
|
||
if (AIControllFlag) // je<6A>li prowadzi komputer
|
||
{ // cz<63><7A><EFBFBD> wykonawcza dla sterowania przez komputer
|
||
if (mvControlling->ConvOvldFlag)
|
||
{ // wywali<6C> bezpiecznik nadmiarowy przetwornicy
|
||
while (DecSpeed(true))
|
||
; // zerowanie nap<61>du
|
||
mvControlling->ConvOvldFlag = false; // reset nadmiarowego
|
||
}
|
||
else if (!mvControlling->Mains)
|
||
{
|
||
// if TrainType=dt_SN61)
|
||
// begin
|
||
// OK:=(OrderDirectionChange(ChangeDir,Controlling)=-1);
|
||
// OK:=IncMainCtrl(1);
|
||
// end;
|
||
while (DecSpeed(true))
|
||
; // zerowanie nap<61>du
|
||
OK = mvControlling->MainSwitch(true);
|
||
if (mvControlling->EngineType == DieselEngine)
|
||
{ // Ra 2014-06: dla SN61 trzeba wrzuci<63> pierwsz<73> pozycj<63> - nie wiem, czy tutaj...
|
||
// kiedy<64> dzia<69>a<EFBFBD>o...
|
||
if (!mvControlling->MainCtrlPos)
|
||
{
|
||
if (mvControlling->RList[0].R ==
|
||
0.0) // gdy na pozycji 0 dawka paliwa jest zerowa, to zga<67>nie
|
||
mvControlling->IncMainCtrl(1); // dlatego trzeba zwi<77>kszy<7A> pozycj<63>
|
||
if (!mvControlling->ScndCtrlPos) // je<6A>li bieg nie zosta<74> ustawiony
|
||
if (!mvControlling->MotorParam[0].AutoSwitch) // gdy biegi r<>czne
|
||
if (mvControlling->MotorParam[0].mIsat == 0.0) // bl,mIsat,fi,mfi
|
||
mvControlling->IncScndCtrl(1); // pierwszy bieg
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{ // Ra: iDirection okre<72>la, w kt<6B>r<EFBFBD> stron<6F> jedzie sk<73>ad wzgl<67>dem sprz<72>g<EFBFBD>w pojazdu z AI
|
||
OK = (OrderDirectionChange(iDirection, mvOccupied) == -1);
|
||
// w EN57 spr<70><72>arka w ra jest zasilana z silnikowego
|
||
mvControlling->CompressorSwitch(true);
|
||
mvControlling->ConverterSwitch(true);
|
||
mvControlling->CompressorSwitch(true);
|
||
}
|
||
}
|
||
else
|
||
OK = mvControlling->Mains;
|
||
}
|
||
else
|
||
OK = false;
|
||
OK = OK && (mvOccupied->ActiveDir != 0) && (mvControlling->CompressorAllow);
|
||
if (OK)
|
||
{
|
||
if (eStopReason == stopSleep) // je<6A>li dotychczas spa<70>
|
||
eStopReason == stopNone; // teraz nie ma powodu do stania
|
||
iEngineActive = 1;
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
iEngineActive = 0;
|
||
return false;
|
||
}
|
||
};
|
||
|
||
bool TController::ReleaseEngine()
|
||
{ // wy<77><79>czanie silnika (test wy<77><79>czenia, a cz<63><7A><EFBFBD> wykonawcza tylko je<6A>li steruje komputer)
|
||
bool OK = false;
|
||
LastReactionTime = 0.0;
|
||
ReactionTime = PrepareTime;
|
||
if (AIControllFlag)
|
||
{ // je<6A>li steruje komputer
|
||
if (mvOccupied->DoorOpenCtrl == 1)
|
||
{ // zamykanie drzwi
|
||
if (mvOccupied->DoorLeftOpened)
|
||
mvOccupied->DoorLeft(false);
|
||
if (mvOccupied->DoorRightOpened)
|
||
mvOccupied->DoorRight(false);
|
||
}
|
||
if (mvOccupied->ActiveDir == 0)
|
||
if (mvControlling->Mains)
|
||
{
|
||
mvControlling->CompressorSwitch(false);
|
||
mvControlling->ConverterSwitch(false);
|
||
if (mvControlling->EnginePowerSource.SourceType == CurrentCollector)
|
||
{
|
||
mvControlling->PantFront(false);
|
||
mvControlling->PantRear(false);
|
||
}
|
||
OK = mvControlling->MainSwitch(false);
|
||
}
|
||
else
|
||
OK = true;
|
||
}
|
||
else if (mvOccupied->ActiveDir == 0)
|
||
OK = mvControlling->Mains; // tylko to testujemy dla pojazdu cz<63>owieka
|
||
if (AIControllFlag)
|
||
if (!mvOccupied->DecBrakeLevel()) // tu moze zmienia<69> na -2, ale to bez znaczenia
|
||
if (!mvOccupied->IncLocalBrakeLevel(1))
|
||
{
|
||
while (DecSpeed(true))
|
||
; // zerowanie nastawnik<69>w
|
||
while (mvOccupied->ActiveDir > 0)
|
||
mvOccupied->DirectionBackward();
|
||
while (mvOccupied->ActiveDir < 0)
|
||
mvOccupied->DirectionForward();
|
||
}
|
||
OK = OK && (mvOccupied->Vel < 0.01);
|
||
if (OK)
|
||
{ // je<6A>li si<73> zatrzyma<6D>
|
||
iEngineActive = 0;
|
||
eStopReason = stopSleep; // stoimy z powodu wy<77><79>czenia
|
||
eAction = actSleep; //<2F>pi (wygaszony)
|
||
if (AIControllFlag)
|
||
{
|
||
Lights(0, 0); // gasimy <20>wiat<61>a
|
||
mvOccupied->BatterySwitch(false);
|
||
}
|
||
OrderNext(Wait_for_orders); //<2F>eby nie pr<70>bowa<77> co<63> robi<62> dalej
|
||
TableClear(); // zapominamy ograniczenia
|
||
iDrivigFlags &= ~moveActive; // ma nie skanowa<77> sygna<6E><61>w i nie reagowa<77> na komendy
|
||
}
|
||
return OK;
|
||
}
|
||
|
||
bool TController::IncBrake()
|
||
{ // zwi<77>kszenie hamowania
|
||
bool OK = false;
|
||
switch (mvOccupied->BrakeSystem)
|
||
{
|
||
case Individual:
|
||
if (mvOccupied->LocalBrake == ManualBrake)
|
||
OK = mvOccupied->IncManualBrakeLevel(1 + floor(0.5 + fabs(AccDesired)));
|
||
else
|
||
OK = mvOccupied->IncLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired)));
|
||
break;
|
||
case Pneumatic:
|
||
if ((mvOccupied->Couplers[0].Connected == NULL) &&
|
||
(mvOccupied->Couplers[1].Connected == NULL))
|
||
OK = mvOccupied->IncLocalBrakeLevel(
|
||
1 + floor(0.5 + fabs(AccDesired))); // hamowanie lokalnym bo luzem jedzie
|
||
else
|
||
{
|
||
if (mvOccupied->BrakeCtrlPos + 1 == mvOccupied->BrakeCtrlPosNo)
|
||
{
|
||
if (AccDesired < -1.5) // hamowanie nagle
|
||
OK = mvOccupied->IncBrakeLevel();
|
||
else
|
||
OK = false;
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
if (AccDesired>-0.2) and ((Vel<20) or (Vel-VelNext<10)))
|
||
begin
|
||
if BrakeCtrlPos>0)
|
||
OK:=IncBrakeLevel
|
||
else;
|
||
OK:=IncLocalBrakeLevel(1); //finezyjne hamowanie lokalnym
|
||
end
|
||
else
|
||
*/
|
||
// dodane dla towarowego
|
||
if (mvOccupied->BrakeDelayFlag == bdelay_G ?
|
||
-AccDesired * 6.6 > Min0R(2, mvOccupied->BrakeCtrlPos) :
|
||
true)
|
||
{
|
||
OK = mvOccupied->IncBrakeLevel();
|
||
}
|
||
else
|
||
OK = false;
|
||
}
|
||
}
|
||
if (mvOccupied->BrakeCtrlPos > 0)
|
||
mvOccupied->BrakeReleaser(0);
|
||
break;
|
||
case ElectroPneumatic:
|
||
if (mvOccupied->EngineType == ElectricInductionMotor)
|
||
{
|
||
OK = mvOccupied->IncLocalBrakeLevel(1);
|
||
}
|
||
else if (mvOccupied->fBrakeCtrlPos != mvOccupied->Handle->GetPos(bh_EPB))
|
||
{
|
||
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EPB));
|
||
if (mvOccupied->Handle->GetPos(bh_EPR) - mvOccupied->Handle->GetPos(bh_EPN) < 0.1)
|
||
mvOccupied->SwitchEPBrake(1); // to nie chce dzia<69>a<EFBFBD>
|
||
OK = true;
|
||
}
|
||
else
|
||
OK = false;
|
||
// if (mvOccupied->BrakeCtrlPos<mvOccupied->BrakeCtrlPosNo)
|
||
// if
|
||
// (mvOccupied->BrakePressureTable[mvOccupied->BrakeCtrlPos+1+2].BrakeType==ElectroPneumatic)
|
||
// //+2 to indeks Pascala
|
||
// OK=mvOccupied->IncBrakeLevel();
|
||
// else
|
||
// OK=false;
|
||
}
|
||
return OK;
|
||
}
|
||
|
||
bool TController::DecBrake()
|
||
{ // zmniejszenie si<73>y hamowania
|
||
bool OK = false;
|
||
switch (mvOccupied->BrakeSystem)
|
||
{
|
||
case Individual:
|
||
if (mvOccupied->LocalBrake == ManualBrake)
|
||
OK = mvOccupied->DecManualBrakeLevel(1 + floor(0.5 + fabs(AccDesired)));
|
||
else
|
||
OK = mvOccupied->DecLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired)));
|
||
break;
|
||
case Pneumatic:
|
||
if (mvOccupied->BrakeCtrlPos > 0)
|
||
OK = mvOccupied->DecBrakeLevel();
|
||
if (!OK)
|
||
OK = mvOccupied->DecLocalBrakeLevel(2);
|
||
if (mvOccupied->PipePress < 3.0)
|
||
Need_BrakeRelease = true;
|
||
break;
|
||
case ElectroPneumatic:
|
||
if (mvOccupied->EngineType == ElectricInductionMotor)
|
||
{
|
||
OK = mvOccupied->DecLocalBrakeLevel(1);
|
||
}
|
||
else if (mvOccupied->fBrakeCtrlPos != mvOccupied->Handle->GetPos(bh_EPR))
|
||
{
|
||
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EPR));
|
||
if (mvOccupied->Handle->GetPos(bh_EPR) - mvOccupied->Handle->GetPos(bh_EPN) < 0.1)
|
||
mvOccupied->SwitchEPBrake(1);
|
||
OK = true;
|
||
}
|
||
else
|
||
OK = false;
|
||
if (!OK)
|
||
OK = mvOccupied->DecLocalBrakeLevel(2);
|
||
break;
|
||
}
|
||
return OK;
|
||
};
|
||
|
||
bool TController::IncSpeed()
|
||
{ // zwi<77>kszenie pr<70>dko<6B>ci; zwraca false, je<6A>li dalej si<73> nie da zwi<77>ksza<7A>
|
||
if (tsGuardSignal) // je<6A>li jest d<>wi<77>k kierownika
|
||
if (tsGuardSignal->GetStatus() & DSBSTATUS_PLAYING) // je<6A>li gada, to nie jedziemy
|
||
return false;
|
||
bool OK = true;
|
||
if (iDrivigFlags & moveDoorOpened)
|
||
Doors(false); // zamykanie drzwi - tutaj wykonuje tylko AI (zmienia fActionTime)
|
||
if (fActionTime < 0.0) // gdy jest nakaz poczeka<6B> z jazd<7A>, to nie rusza<7A>
|
||
return false;
|
||
if (mvControlling->SlippingWheels)
|
||
return false; // jak po<70>lizg, to nie przyspieszamy
|
||
switch (mvOccupied->EngineType)
|
||
{
|
||
case None: // McZapkie-041003: wagon sterowniczy
|
||
if (mvControlling->MainCtrlPosNo > 0) // je<6A>li ma czym kr<6B>ci<63>
|
||
iDrivigFlags |= moveIncSpeed; // ustawienie flagi jazdy
|
||
return false;
|
||
case ElectricSeriesMotor:
|
||
if (mvControlling->EnginePowerSource.SourceType == CurrentCollector) // je<6A>li pantografuj<75>cy
|
||
{
|
||
if (fOverhead2 >= 0.0) // a jazda bezpr<70>dowa ustawiana eventami (albo opuszczenie)
|
||
return false; // to nici z ruszania
|
||
if (iOverheadZero) // jazda bezpr<70>dowa z poziomu toru ustawia bity
|
||
return false; // to nici z ruszania
|
||
}
|
||
if (!mvControlling->FuseFlag) //&&mvControlling->StLinFlag) //yBARC
|
||
if ((mvControlling->MainCtrlPos == 0) ||
|
||
(mvControlling->StLinFlag)) // youBy poleci<63> doda<64> 2012-09-08 v367
|
||
// na pozycji 0 przejdzie, a na pozosta<74>ych b<>dzie czeka<6B>, a<> si<73> za<7A><61>cz<63> liniowe
|
||
// (zga<67>nie DelayCtrlFlag)
|
||
if (Ready || (iDrivigFlags & movePress))
|
||
if (fabs(mvControlling->Im) <
|
||
(fReady < 0.4 ? mvControlling->Imin : mvControlling->IminLo))
|
||
{ // Ra: wywala<6C> nadmiarowy, bo Im mo<6D>e by<62> ujemne; jak nie odhamowany, to nie
|
||
// przesadza<7A> z pr<70>dem
|
||
if ((mvOccupied->Vel <= 30) ||
|
||
(mvControlling->Imax > mvControlling->ImaxLo) ||
|
||
(fVoltage + fVoltage <
|
||
mvControlling->EnginePowerSource.CollectorParameters.MinV +
|
||
mvControlling->EnginePowerSource.CollectorParameters.MaxV))
|
||
{ // bocznik na szeregowej przy ciezkich bruttach albo przy wysokim rozruchu
|
||
// pod g<>r<EFBFBD> albo przy niskim napi<70>ciu
|
||
if (mvControlling->MainCtrlPos ?
|
||
mvControlling->RList[mvControlling->MainCtrlPos].R > 0.0 :
|
||
true) // oporowa
|
||
{
|
||
OK = (mvControlling->DelayCtrlFlag ?
|
||
true :
|
||
mvControlling->IncMainCtrl(1)); // kr<6B>cimy nastawnik jazdy
|
||
if ((OK) &&
|
||
(mvControlling->MainCtrlPos ==
|
||
1)) // czekaj na 1 pozycji, zanim si<73> nie w<><77>cz<63> liniowe
|
||
iDrivigFlags |= moveIncSpeed;
|
||
else
|
||
iDrivigFlags &= ~moveIncSpeed; // usuni<6E>cie flagi czekania
|
||
}
|
||
else // je<6A>li bezoporowa (z wyj<79>tekiem 0)
|
||
OK = false; // to da<64> bocznik
|
||
}
|
||
else
|
||
{ // przekroczone 30km/h, mo<6D>na wej<65><6A> na jazd<7A> r<>wnoleg<65><67>
|
||
if (mvControlling->ScndCtrlPos) // je<6A>li ustawiony bocznik
|
||
if (mvControlling->MainCtrlPos <
|
||
mvControlling->MainCtrlPosNo - 1) // a nie jest ostatnia pozycja
|
||
mvControlling->DecScndCtrl(2); // to bocznik na zero po chamsku
|
||
// (kto<74> mia<69> to poprawi<77>...)
|
||
OK = mvControlling->IncMainCtrl(1);
|
||
}
|
||
if ((mvControlling->MainCtrlPos > 2) &&
|
||
(mvControlling->Im == 0)) // brak pr<70>du na dalszych pozycjach
|
||
Need_TryAgain = true; // nie za<7A><61>czona lokomotywa albo wywali<6C>
|
||
// nadmiarowy
|
||
else if (!OK) // nie da si<73> wrzuci<63> kolejnej pozycji
|
||
OK = mvControlling->IncScndCtrl(1); // to da<64> bocznik
|
||
}
|
||
mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania
|
||
break;
|
||
case Dumb:
|
||
case DieselElectric:
|
||
if (!mvControlling->FuseFlag)
|
||
if (Ready || (iDrivigFlags & movePress)) //{(BrakePress<=0.01*MaxBrakePress)}
|
||
{
|
||
OK = mvControlling->IncMainCtrl(1);
|
||
if (!OK)
|
||
OK = mvControlling->IncScndCtrl(1);
|
||
}
|
||
break;
|
||
case ElectricInductionMotor:
|
||
if (!mvControlling->FuseFlag)
|
||
if (Ready || (iDrivigFlags & movePress) || (mvOccupied->ShuntMode)) //{(BrakePress<=0.01*MaxBrakePress)}
|
||
{
|
||
OK = mvControlling->IncMainCtrl(1);
|
||
}
|
||
break;
|
||
break;
|
||
case WheelsDriven:
|
||
if (!mvControlling->CabNo)
|
||
mvControlling->CabActivisation();
|
||
if (sin(mvControlling->eAngle) > 0)
|
||
mvControlling->IncMainCtrl(3 + 3 * floor(0.5 + fabs(AccDesired)));
|
||
else
|
||
mvControlling->DecMainCtrl(3 + 3 * floor(0.5 + fabs(AccDesired)));
|
||
break;
|
||
case DieselEngine:
|
||
if (mvControlling->ShuntModeAllow)
|
||
{ // dla 2Ls150 mo<6D>na zmieni<6E> tryb pracy, je<6A>li jest w liniowym i nie daje rady (wymaga
|
||
// zerowania kierunku)
|
||
// mvControlling->ShuntMode=(OrderList[OrderPos]&Shunt)||(fMass>224000.0);
|
||
}
|
||
if ((mvControlling->Vel > mvControlling->dizel_minVelfullengage) &&
|
||
(mvControlling->RList[mvControlling->MainCtrlPos].Mn > 0))
|
||
OK = mvControlling->IncMainCtrl(1);
|
||
if (mvControlling->RList[mvControlling->MainCtrlPos].Mn == 0)
|
||
OK = mvControlling->IncMainCtrl(1);
|
||
if (!mvControlling->Mains)
|
||
{
|
||
mvControlling->MainSwitch(true);
|
||
mvControlling->ConverterSwitch(true);
|
||
mvControlling->CompressorSwitch(true);
|
||
}
|
||
break;
|
||
}
|
||
return OK;
|
||
}
|
||
|
||
bool TController::DecSpeed(bool force)
|
||
{ // zmniejszenie pr<70>dko<6B>ci (ale nie hamowanie)
|
||
bool OK = false; // domy<6D>lnie false, aby wysz<73>o z p<>tli while
|
||
switch (mvOccupied->EngineType)
|
||
{
|
||
case None: // McZapkie-041003: wagon sterowniczy
|
||
iDrivigFlags &= ~moveIncSpeed; // usuni<6E>cie flagi jazdy
|
||
if (force) // przy aktywacji kabiny jest potrzeba natychmiastowego wyzerowania
|
||
if (mvControlling->MainCtrlPosNo > 0) // McZapkie-041003: wagon sterowniczy, np. EZT
|
||
mvControlling->DecMainCtrl(1 + (mvControlling->MainCtrlPos > 2 ? 1 : 0));
|
||
mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania
|
||
return false;
|
||
case ElectricSeriesMotor:
|
||
OK = mvControlling->DecScndCtrl(2); // najpierw bocznik na zero
|
||
if (!OK)
|
||
OK = mvControlling->DecMainCtrl(1 + (mvControlling->MainCtrlPos > 2 ? 1 : 0));
|
||
mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania
|
||
break;
|
||
case Dumb:
|
||
case DieselElectric:
|
||
case ElectricInductionMotor:
|
||
OK = mvControlling->DecScndCtrl(2);
|
||
if (!OK)
|
||
OK = mvControlling->DecMainCtrl(2 + (mvControlling->MainCtrlPos / 2));
|
||
break;
|
||
case WheelsDriven:
|
||
if (!mvControlling->CabNo)
|
||
mvControlling->CabActivisation();
|
||
if (sin(mvControlling->eAngle) < 0)
|
||
mvControlling->IncMainCtrl(3 + 3 * floor(0.5 + fabs(AccDesired)));
|
||
else
|
||
mvControlling->DecMainCtrl(3 + 3 * floor(0.5 + fabs(AccDesired)));
|
||
break;
|
||
case DieselEngine:
|
||
if ((mvControlling->Vel > mvControlling->dizel_minVelfullengage))
|
||
{
|
||
if (mvControlling->RList[mvControlling->MainCtrlPos].Mn > 0)
|
||
OK = mvControlling->DecMainCtrl(1);
|
||
}
|
||
else
|
||
while ((mvControlling->RList[mvControlling->MainCtrlPos].Mn > 0) &&
|
||
(mvControlling->MainCtrlPos > 1))
|
||
OK = mvControlling->DecMainCtrl(1);
|
||
if (force) // przy aktywacji kabiny jest potrzeba natychmiastowego wyzerowania
|
||
OK = mvControlling->DecMainCtrl(1 + (mvControlling->MainCtrlPos > 2 ? 1 : 0));
|
||
break;
|
||
}
|
||
return OK;
|
||
};
|
||
|
||
void TController::SpeedSet()
|
||
{ // Ra: regulacja pr<70>dko<6B>ci, wykonywana w ka<6B>dym przeb<65>ysku <20>wiadomo<6D>ci AI
|
||
// ma dokr<6B>ca<63> do bezoporowych i zdejmowa<77> pozycje w przypadku przekroczenia pr<70>du
|
||
switch (mvOccupied->EngineType)
|
||
{
|
||
case None: // McZapkie-041003: wagon sterowniczy
|
||
if (fActionTime >= -1.0)
|
||
mvOccupied->DepartureSignal = false; // troch<63> niech pobuczy, zanim pojedzie
|
||
if (mvControlling->MainCtrlPosNo > 0)
|
||
{ // je<6A>li ma czym kr<6B>ci<63>
|
||
// TODO: sprawdzanie innego czlonu //if (!FuseFlagCheck())
|
||
if ((AccDesired < fAccGravity - 0.05) ||
|
||
(mvOccupied->Vel > VelDesired)) // je<6A>li nie ma przyspiesza<7A>
|
||
mvControlling->DecMainCtrl(2); // na zero
|
||
else if (fActionTime >= 0.0)
|
||
{ // jak ju<6A> mo<6D>na co<63> porusza<7A>, przetok roz<6F><7A>cza<7A> od razu
|
||
if (iDrivigFlags & moveIncSpeed)
|
||
{ // jak ma jecha<68>
|
||
if (fReady < 0.4) // 0.05*Controlling->MaxBrakePress)
|
||
{ // jak jest odhamowany
|
||
if (mvOccupied->ActiveDir > 0)
|
||
mvOccupied->DirectionForward(); //<2F>eby EN57 jecha<68>y na drugiej nastawie
|
||
{
|
||
if (mvControlling->MainCtrlPos &&
|
||
!mvControlling
|
||
->StLinFlag) // jak niby jedzie, ale ma roz<6F><7A>czone liniowe
|
||
mvControlling->DecMainCtrl(
|
||
2); // to na zero i czeka<6B> na przewalenie ku<6B>akowego
|
||
else
|
||
switch (mvControlling->MainCtrlPos)
|
||
{ // ruch nastawnika uzale<6C>niony jest od aktualnie ustawionej
|
||
// pozycji
|
||
case 0:
|
||
if (mvControlling->MainCtrlActualPos) // je<6A>li ku<6B>akowy nie jest
|
||
// wyzerowany
|
||
break; // to czeka<6B> na wyzerowanie
|
||
mvControlling->IncMainCtrl(1); // przetok; bez "break", bo nie
|
||
// ma czekania na 1. pozycji
|
||
case 1:
|
||
if (VelDesired >= 20)
|
||
mvControlling->IncMainCtrl(1); // szeregowa
|
||
case 2:
|
||
if (VelDesired >= 50)
|
||
mvControlling->IncMainCtrl(1); // r<>wnoleg<65>a
|
||
case 3:
|
||
if (VelDesired >= 80)
|
||
mvControlling->IncMainCtrl(1); // bocznik 1
|
||
case 4:
|
||
if (VelDesired >= 90)
|
||
mvControlling->IncMainCtrl(1); // bocznik 2
|
||
case 5:
|
||
if (VelDesired >= 100)
|
||
mvControlling->IncMainCtrl(1); // bocznik 3
|
||
}
|
||
if (mvControlling->MainCtrlPos) // jak za<7A><61>czy<7A> pozycj<63>
|
||
{
|
||
fActionTime = -5.0; // niech troch<63> potrzyma
|
||
mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
while (mvControlling->MainCtrlPos)
|
||
mvControlling->DecMainCtrl(1); // na zero
|
||
fActionTime = -5.0; // niech troch<63> potrzyma
|
||
mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case ElectricSeriesMotor:
|
||
if ((!mvControlling->StLinFlag) && (!mvControlling->DelayCtrlFlag) &&
|
||
(!iDrivigFlags & moveIncSpeed)) // styczniki liniowe roz<6F><7A>czone yBARC
|
||
// if (iDrivigFlags&moveIncSpeed) {} //je<6A>li czeka na za<7A><61>czenie liniowych
|
||
// else
|
||
while (DecSpeed())
|
||
; // zerowanie nap<61>du
|
||
else if (Ready || (iDrivigFlags & movePress)) // o ile mo<6D>e jecha<68>
|
||
if (fAccGravity < -0.10) // i jedzie pod g<>r<EFBFBD> wi<77>ksz<73> ni<6E> 10 promil
|
||
{ // procedura wje<6A>d<EFBFBD>ania na ekstremalne wzniesienia
|
||
if (fabs(mvControlling->Im) >
|
||
0.85 * mvControlling->Imax) // a pr<70>d jest wi<77>kszy ni<6E> 85% nadmiarowego
|
||
// if (mvControlling->Imin*mvControlling->Voltage/(fMass*fAccGravity)<-2.8) //a
|
||
// na niskim si<73> za szybko nie pojedzie
|
||
if (mvControlling->Imax * mvControlling->Voltage / (fMass * fAccGravity) <
|
||
-2.8) // a na niskim si<73> za szybko nie pojedzie
|
||
{ // w<><77>czenie wysokiego rozruchu;
|
||
// (I*U)[A*V=W=kg*m*m/sss]/(m[kg]*a[m/ss])=v[m/s]; 2.8m/ss=10km/h
|
||
if (mvControlling->RList[mvControlling->MainCtrlPos].Bn > 1)
|
||
{ // je<6A>li jedzie na r<>wnoleg<65>ym, to zbijamy do szeregowego, aby w<><77>czy<7A>
|
||
// wysoki rozruch
|
||
if (mvControlling->ScndCtrlPos > 0) // je<6A>eli jest bocznik
|
||
mvControlling->DecScndCtrl(
|
||
2); // wy<77><79>czy<7A> bocznik, bo mo<6D>e blokowa<77> skr<6B>cenie NJ
|
||
do // skr<6B>canie do bezoporowej na szeregowym
|
||
mvControlling->DecMainCtrl(1); // kr<6B>cimy nastawnik jazdy o 1 wstecz
|
||
while (mvControlling->MainCtrlPos ?
|
||
mvControlling->RList[mvControlling->MainCtrlPos].Bn > 1 :
|
||
false); // oporowa zap<61>tla
|
||
}
|
||
if (mvControlling->Imax < mvControlling->ImaxHi) // je<6A>li da si<73> na wysokim
|
||
mvControlling->CurrentSwitch(
|
||
true); // rozruch wysoki (za to mo<6D>e si<73> <20>lizga<67>)
|
||
if (ReactionTime > 0.1)
|
||
ReactionTime = 0.1; // orientuj si<73> szybciej
|
||
} // if (Im>Imin)
|
||
if (fabs(mvControlling->Im) > 0.75 * mvControlling->ImaxHi) // je<6A>li pr<70>d jest du<64>y
|
||
mvControlling->SandDoseOn(); // piaskujemy tory, coby si<73> nie <20>lizga<67>
|
||
if ((fabs(mvControlling->Im) > 0.96 * mvControlling->Imax) ||
|
||
mvControlling->SlippingWheels) // je<6A>li pr<70>d jest du<64>y (mo<6D>na 690 na 750)
|
||
if (mvControlling->ScndCtrlPos > 0) // je<6A>eli jest bocznik
|
||
mvControlling->DecScndCtrl(2); // zmniejszy<7A> bocznik
|
||
else
|
||
mvControlling->DecMainCtrl(1); // kr<6B>cimy nastawnik jazdy o 1 wstecz
|
||
}
|
||
else // gdy nie jedzie ambitnie pod g<>r<EFBFBD>
|
||
{ // sprawdzenie, czy rozruch wysoki jest potrzebny
|
||
if (mvControlling->Imax > mvControlling->ImaxLo)
|
||
if (mvOccupied->Vel >= 30.0) // jak si<73> rozp<7A>dzi<7A>
|
||
if (fAccGravity > -0.02) // a i pochylenie mnijsze ni<6E> 2<>
|
||
mvControlling->CurrentSwitch(false); // rozruch wysoki wy<77><79>cz
|
||
// dokr<6B>canie do bezoporowej, bo IncSpeed() mo<6D>e nie by<62> wywo<77>ywane
|
||
// if (mvOccupied->Vel<VelDesired)
|
||
// if (AccDesired>-0.1) //nie ma hamowa<77>
|
||
// if (Controlling->RList[MainCtrlPos].R>0.0)
|
||
// if (Im<1.3*Imin) //lekkie przekroczenie miimalnego pr<70>du jest dopuszczalne
|
||
// IncMainCtrl(1); //zwieksz nastawnik skoro mo<6D>esz - tak aby si<73> ustawic na
|
||
// bezoporowej
|
||
}
|
||
break;
|
||
case Dumb:
|
||
case DieselElectric:
|
||
case ElectricInductionMotor:
|
||
break;
|
||
// WheelsDriven :
|
||
// begin
|
||
// OK:=False;
|
||
// end;
|
||
case DieselEngine:
|
||
// Ra 2014-06: "automatyczna" skrzynia bieg<65>w...
|
||
if (!mvControlling->MotorParam[mvControlling->ScndCtrlPos].AutoSwitch) // gdy biegi r<>czne
|
||
if ((mvControlling->ShuntMode ? mvControlling->AnPos : 1.0) * mvControlling->Vel >
|
||
0.6 * mvControlling->MotorParam[mvControlling->ScndCtrlPos].mfi)
|
||
// if (mvControlling->enrot>0.95*mvControlling->dizel_nMmax) //youBy: je<6A>li obroty >
|
||
// 0,95 nmax, wrzu<7A> wy<77>szy bieg - Ra: to nie dzia<69>a
|
||
{ // jak pr<70>dko<6B><6F> wi<77>ksza ni<6E> 0.6 maksymalnej na danym biegu, wrzuci<63> wy<77>szy
|
||
mvControlling->DecMainCtrl(2);
|
||
if (mvControlling->IncScndCtrl(1))
|
||
if (mvControlling->MotorParam[mvControlling->ScndCtrlPos].mIsat ==
|
||
0.0) // je<6A>li bieg ja<6A>owy
|
||
mvControlling->IncScndCtrl(1); // to kolejny
|
||
}
|
||
else if ((mvControlling->ShuntMode ? mvControlling->AnPos : 1.0) * mvControlling->Vel <
|
||
mvControlling->MotorParam[mvControlling->ScndCtrlPos].fi)
|
||
{ // jak pr<70>dko<6B><6F> mniejsza ni<6E> minimalna na danym biegu, wrzuci<63> ni<6E>szy
|
||
mvControlling->DecMainCtrl(2);
|
||
mvControlling->DecScndCtrl(1);
|
||
if (mvControlling->MotorParam[mvControlling->ScndCtrlPos].mIsat ==
|
||
0.0) // je<6A>li bieg ja<6A>owy
|
||
if (mvControlling->ScndCtrlPos) // a jeszcze zera nie osi<73>gni<6E>to
|
||
mvControlling->DecScndCtrl(1); // to kolejny wcze<7A>niejszy
|
||
else
|
||
mvControlling->IncScndCtrl(1); // a jak zesz<73>o na zero, to powr<77>t
|
||
}
|
||
break;
|
||
}
|
||
};
|
||
|
||
void TController::Doors(bool what)
|
||
{ // otwieranie/zamykanie drzwi w sk<73>adzie albo (tylko AI) EZT
|
||
if (what)
|
||
{ // otwarcie
|
||
}
|
||
else
|
||
{ // zamykanie
|
||
if (mvOccupied->DoorOpenCtrl == 1)
|
||
{ // je<6A>li drzwi sterowane z kabiny
|
||
if (AIControllFlag)
|
||
if (mvOccupied->DoorLeftOpened || mvOccupied->DoorRightOpened)
|
||
{ // AI zamyka drzwi przed odjazdem
|
||
if (mvOccupied->DoorClosureWarning)
|
||
mvOccupied->DepartureSignal = true; // za<7A><61>cenie bzyczka
|
||
mvOccupied->DoorLeft(false); // zamykanie drzwi
|
||
mvOccupied->DoorRight(false);
|
||
// Ra: trzeba by ustawi<77> jaki<6B> czas oczekiwania na zamkni<6E>cie si<73> drzwi
|
||
fActionTime = -1.5 - 0.1 * random(10); // czekanie sekund<6E>, mo<6D>e troch<63> d<>u<EFBFBD>ej
|
||
iDrivigFlags &= ~moveDoorOpened; // nie wykonywa<77> drugi raz
|
||
}
|
||
}
|
||
else
|
||
{ // je<6A>li nie, to zamykanie w sk<73>adzie wagonowym
|
||
TDynamicObject *p = pVehicles[0]; // pojazd na czole sk<73>adu
|
||
while (p)
|
||
{ // zamykanie drzwi w pojazdach - flaga zezwolenia by<62>a by lepsza
|
||
p->MoverParameters->DoorLeft(false); // w lokomotywie mo<6D>na by nie zamyka<6B>...
|
||
p->MoverParameters->DoorRight(false);
|
||
p = p->Next(); // pojazd pod<6F><64>czony z ty<74>u (patrz<72>c od czo<7A>a)
|
||
}
|
||
// WaitingSet(5); //10 sekund tu to za d<>ugo, op<6F><70>nia odjazd o p<><70> minuty
|
||
fActionTime = -1.5 - 0.1 * random(10); // czekanie sekund<6E>, mo<6D>e troch<63> d<>u<EFBFBD>ej
|
||
iDrivigFlags &= ~moveDoorOpened; // zosta<74>y zamkni<6E>te - nie wykonywa<77> drugi raz
|
||
}
|
||
}
|
||
};
|
||
|
||
void TController::RecognizeCommand()
|
||
{ // odczytuje i wykonuje komend<6E> przekazan<61> lokomotywie
|
||
TCommand *c = &mvOccupied->CommandIn;
|
||
PutCommand(c->Command, c->Value1, c->Value2, c->Location, stopComm);
|
||
c->Command = ""; // usuni<6E>cie obs<62>u<EFBFBD>onej komendy
|
||
}
|
||
|
||
void TController::PutCommand(std::string NewCommand, double NewValue1, double NewValue2,
|
||
const TLocation &NewLocation, TStopReason reason)
|
||
{ // wys<79>anie komendy przez event PutValues, jak pojazd ma obsad<61>, to wysy<73>a tutaj, a nie do pojazdu
|
||
// bezpo<70>rednio
|
||
vector3 sl;
|
||
sl.x = -NewLocation.X; // zamiana na wsp<73><70>rz<72>dne scenerii
|
||
sl.z = NewLocation.Y;
|
||
sl.y = NewLocation.Z;
|
||
if (!PutCommand(NewCommand, NewValue1, NewValue2, &sl, reason))
|
||
mvOccupied->PutCommand(NewCommand, NewValue1, NewValue2, NewLocation);
|
||
}
|
||
|
||
bool TController::PutCommand(std::string NewCommand, double NewValue1, double NewValue2,
|
||
const vector3 *NewLocation, TStopReason reason)
|
||
{ // analiza komendy
|
||
if (NewCommand == "CabSignal")
|
||
{ // SHP wyzwalane jest przez cz<63>on z obsad<61>, ale obs<62>ugiwane przez silnikowy
|
||
// nie jest to najlepiej zrobione, ale bez symulacji obwod<6F>w lepiej nie b<>dzie
|
||
// Ra 2014-04: jednak przenios<6F>em do rozrz<72>dczego
|
||
mvOccupied->PutCommand(NewCommand, NewValue1, NewValue2, mvOccupied->Loc);
|
||
mvOccupied->RunInternalCommand(); // rozpoznaj komende bo lokomotywa jej nie rozpoznaje
|
||
return true; // za<7A>atwione
|
||
}
|
||
if (NewCommand == "Overhead")
|
||
{ // informacja o stanie sieci trakcyjnej
|
||
fOverhead1 =
|
||
NewValue1; // informacja o napi<70>ciu w sieci trakcyjnej (0=brak drutu, zatrzymaj!)
|
||
fOverhead2 = NewValue2; // informacja o sposobie jazdy (-1=normalnie, 0=bez pr<70>du, >0=z
|
||
// opuszczonym i ograniczeniem pr<70>dko<6B>ci)
|
||
return true; // za<7A>atwione
|
||
}
|
||
else if (NewCommand == "Emergency_brake") // wymuszenie zatrzymania, niezale<6C>nie kto prowadzi
|
||
{ // Ra: no nadal nie jest zbyt pi<70>knie
|
||
SetVelocity(0, 0, reason);
|
||
mvOccupied->PutCommand("Emergency_brake", 1.0, 1.0, mvOccupied->Loc);
|
||
return true; // za<7A>atwione
|
||
}
|
||
else if (NewCommand.find("Timetable:") == 0)
|
||
{ // przypisanie nowego rozk<7A>adu jazdy, r<>wnie<69> prowadzonemu przez u<>ytkownika
|
||
NewCommand = NewCommand.erase(0, 10); // zostanie nazwa pliku z rozk<7A>adem
|
||
#if LOGSTOPS
|
||
WriteLog("New timetable for " + pVehicle->asName + ": " + NewCommand); // informacja
|
||
#endif
|
||
if (!TrainParams)
|
||
TrainParams = new TTrainParameters(NewCommand); // rozk<7A>ad jazdy
|
||
else
|
||
TrainParams->NewName(NewCommand); // czy<7A>ci tabelk<6C> przystank<6E>w
|
||
delete tsGuardSignal;
|
||
tsGuardSignal = NULL; // wywalenie kierownika
|
||
if (NewCommand != "none")
|
||
{
|
||
if (!TrainParams->LoadTTfile(
|
||
std::string(Global::asCurrentSceneryPath.c_str()), floor(NewValue2 + 0.5),
|
||
NewValue1)) // pierwszy parametr to przesuni<6E>cie rozk<7A>adu w czasie
|
||
{
|
||
if (ConversionError == -8)
|
||
ErrorLog("Missed timetable: " + NewCommand);
|
||
WriteLog("Cannot load timetable file " + NewCommand + "\r\nError " +
|
||
to_string(ConversionError) + " in position " + to_string(TrainParams->StationCount));
|
||
NewCommand = ""; // puste, dla wymiennej tekstury
|
||
}
|
||
else
|
||
{ // inicjacja pierwszego przystanku i pobranie jego nazwy
|
||
TrainParams->UpdateMTable(GlobalTime->hh, GlobalTime->mm,
|
||
TrainParams->NextStationName);
|
||
TrainParams->StationIndexInc(); // przej<65>cie do nast<73>pnej
|
||
iStationStart = TrainParams->StationIndex;
|
||
asNextStop = TrainParams->NextStop();
|
||
iDrivigFlags |= movePrimary; // skoro dosta<74> rozk<7A>ad, to jest teraz g<><67>wnym
|
||
NewCommand = Global::asCurrentSceneryPath + NewCommand + ".wav"; // na razie jeden
|
||
if (fileExists(NewCommand))
|
||
{ // wczytanie d<>wi<77>ku odjazdu podawanego bezpo<70>renido
|
||
tsGuardSignal = new TTextSound(NewCommand.c_str(), 30, pVehicle->GetPosition().x,
|
||
pVehicle->GetPosition().y, pVehicle->GetPosition().z,
|
||
false);
|
||
// rsGuardSignal->Stop();
|
||
iGuardRadio = 0; // nie przez radio
|
||
}
|
||
else
|
||
{
|
||
NewCommand = NewCommand.insert(NewCommand.find_last_of("."),"radio"); // wstawienie przed kropk<70>
|
||
if (fileExists(NewCommand))
|
||
{ // wczytanie d<>wi<77>ku odjazdu w wersji radiowej (s<>ycha<68> tylko w kabinie)
|
||
tsGuardSignal = new TTextSound(NewCommand.c_str(), -1, pVehicle->GetPosition().x,
|
||
pVehicle->GetPosition().y, pVehicle->GetPosition().z,
|
||
false);
|
||
iGuardRadio = iRadioChannel;
|
||
}
|
||
}
|
||
NewCommand = TrainParams->Relation2; // relacja docelowa z rozk<7A>adu
|
||
}
|
||
// jeszcze poustawia<69> tekstury na wy<77>wietlaczach
|
||
TDynamicObject *p = pVehicles[0];
|
||
while (p)
|
||
{
|
||
p->DestinationSet(NewCommand, TrainParams->TrainName); // relacja docelowa
|
||
p = p->Next(); // pojazd pod<6F><64>czony od ty<74>u (licz<63>c od czo<7A>a)
|
||
}
|
||
}
|
||
if (NewLocation) // je<6A>li podane wsp<73><70>rz<72>dne eventu/kom<6F>rki ustawiaj<61>cej rozk<7A>ad (trainset
|
||
// nie podaje)
|
||
{
|
||
vector3 v = *NewLocation - pVehicle->GetPosition(); // wektor do punktu steruj<75>cego
|
||
vector3 d = pVehicle->VectorFront(); // wektor wskazuj<75>cy prz<72>d
|
||
iDirectionOrder = ((v.x * d.x + v.z * d.z) * NewValue1 > 0) ?
|
||
1 :
|
||
-1; // do przodu, gdy iloczyn skalarny i pr<70>dko<6B><6F> dodatnie
|
||
/*
|
||
if (NewValue1!=0.0) //je<6A>li ma jecha<68>
|
||
if (iDirectionOrder==0) //a kierunek nie by<62> okre<72>lony (normalnie okre<72>lany przez
|
||
reardriver/headdriver)
|
||
iDirectionOrder=NewValue1>0?1:-1; //ustalenie kierunku jazdy wzgl<67>dem sprz<72>g<EFBFBD>w
|
||
else
|
||
if (NewValue1<0) //dla ujemnej pr<70>dko<6B>ci
|
||
iDirectionOrder=-iDirectionOrder; //ma jecha<68> w drug<75> stron<6F>
|
||
*/
|
||
if (AIControllFlag) // je<6A>li prowadzi komputer
|
||
Activation(); // umieszczenie obs<62>ugi we w<>a<EFBFBD>ciwym cz<63>onie, ustawienie nawrotnika w
|
||
// prz<72>d
|
||
}
|
||
/*
|
||
else
|
||
if (!iDirectionOrder)
|
||
{//je<6A>li nie ma kierunku, trzeba ustali<6C>
|
||
if (mvOccupied->V!=0.0)
|
||
iDirectionOrder=mvOccupied->V>0?1:-1;
|
||
else
|
||
iDirectionOrder=mvOccupied->ActiveCab;
|
||
if (!iDirectionOrder) iDirectionOrder=1;
|
||
}
|
||
*/
|
||
// je<6A>li wysy<73>ane z Trainset, to wszystko jest ju<6A> odpowiednio ustawione
|
||
// if (!NewLocation) //je<6A>li wysy<73>ane z Trainset
|
||
// if (mvOccupied->CabNo*mvOccupied->V*NewValue1<0) //je<6A>li zadana pr<70>dko<6B><6F> niezgodna z
|
||
// aktualnym kierunkiem jazdy
|
||
// DirectionForward(false); //jedziemy do ty<74>u (nawrotnik do ty<74>u)
|
||
// CheckVehicles(); //sprawdzenie sk<73>adu, AI zapali <20>wiat<61>a
|
||
TableClear(); // wyczyszczenie tabelki pr<70>dko<6B>ci, bo na nowo trzeba okre<72>li<6C> kierunek i
|
||
// sprawdzi<7A> przystanki
|
||
OrdersInit(
|
||
fabs(NewValue1)); // ustalenie tabelki komend wg rozk<7A>adu oraz pr<70>dko<6B>ci pocz<63>tkowej
|
||
// if (NewValue1!=0.0) if (!AIControllFlag) DirectionForward(NewValue1>0.0); //ustawienie
|
||
// nawrotnika u<>ytkownikowi (propaguje si<73> do cz<63>on<6F>w)
|
||
// if (NewValue1>0)
|
||
// TrainNumber=floor(NewValue1); //i co potem ???
|
||
return true; // za<7A>atwione
|
||
}
|
||
if (NewCommand == "SetVelocity")
|
||
{
|
||
if (NewLocation)
|
||
vCommandLocation = *NewLocation;
|
||
if ((NewValue1 != 0.0) && (OrderList[OrderPos] != Obey_train))
|
||
{ // o ile jazda
|
||
if (!iEngineActive)
|
||
OrderNext(Prepare_engine); // trzeba odpali<6C> silnik najpierw, <20>wiat<61>a ustawi
|
||
// JumpToNextOrder()
|
||
// if (OrderList[OrderPos]!=Obey_train) //je<6A>li nie poci<63>gowa
|
||
OrderNext(Obey_train); // to uruchomi<6D> jazd<7A> poci<63>gow<6F> (od razu albo po odpaleniu
|
||
// silnika
|
||
OrderCheck(); // je<6A>li jazda poci<63>gowa teraz, to wykona<6E> niezb<7A>dne operacje
|
||
}
|
||
if (NewValue1 != 0.0) // je<6A>li jecha<68>
|
||
iDrivigFlags &= ~moveStopHere; // podje<6A>anie do semafor<6F>w zezwolone
|
||
else
|
||
iDrivigFlags |= moveStopHere; // sta<74> do momentu podania komendy jazdy
|
||
SetVelocity(NewValue1, NewValue2, reason); // bylo: nic nie rob bo SetVelocity zewnetrznie
|
||
// jest wywolywane przez dynobj.cpp
|
||
}
|
||
else if (NewCommand == "SetProximityVelocity")
|
||
{
|
||
/*
|
||
if (SetProximityVelocity(NewValue1,NewValue2))
|
||
if (NewLocation)
|
||
vCommandLocation=*NewLocation;
|
||
*/
|
||
}
|
||
else if (NewCommand == "ShuntVelocity")
|
||
{ // uruchomienie jazdy manewrowej b<>d<EFBFBD> zmiana pr<70>dko<6B>ci
|
||
if (NewLocation)
|
||
vCommandLocation = *NewLocation;
|
||
// if (OrderList[OrderPos]=Obey_train) and (NewValue1<>0))
|
||
if (!iEngineActive)
|
||
OrderNext(Prepare_engine); // trzeba odpali<6C> silnik najpierw
|
||
OrderNext(Shunt); // zamieniamy w aktualnej pozycji, albo dodajey za odpaleniem silnika
|
||
if (NewValue1 != 0.0)
|
||
{
|
||
// if (iVehicleCount>=0) WriteLog("Skasowano ilos<6F> wagon<6F>w w ShuntVelocity!");
|
||
iVehicleCount = -2; // warto<74><6F> neutralna
|
||
CheckVehicles(); // zabra<72> to do OrderCheck()
|
||
}
|
||
// dla pr<70>dko<6B>ci ujemnej przestawi<77> nawrotnik do ty<74>u? ale -1=brak ograniczenia !!!!
|
||
// if (iDrivigFlags&movePress) WriteLog("Skasowano docisk w ShuntVelocity!");
|
||
iDrivigFlags &= ~movePress; // bez dociskania
|
||
SetVelocity(NewValue1, NewValue2, reason);
|
||
if (NewValue1 != 0.0)
|
||
iDrivigFlags &= ~moveStopHere; // podje<6A>anie do semafor<6F>w zezwolone
|
||
else
|
||
iDrivigFlags |= moveStopHere; // ma sta<74> w miejscu
|
||
if (fabs(NewValue1) > 2.0) // o ile warto<74><6F> jest sensowna (-1 nie jest konkretn<74> warto<74>ci<63>)
|
||
fShuntVelocity = fabs(NewValue1); // zapami<6D>tanie obowi<77>zuj<75>cej pr<70>dko<6B>ci dla manewr<77>w
|
||
}
|
||
else if (NewCommand == "Wait_for_orders")
|
||
{ // oczekiwanie; NewValue1 - czas oczekiwania, -1 = na inn<6E> komend<6E>
|
||
if (NewValue1 > 0.0 ? NewValue1 > fStopTime : false)
|
||
fStopTime = NewValue1; // Ra: w<><77>czenie czekania bez zmiany komendy
|
||
else
|
||
OrderList[OrderPos] = Wait_for_orders; // czekanie na komend<6E> (albo da<64> OrderPos=0)
|
||
}
|
||
else if (NewCommand == "Prepare_engine")
|
||
{ // w<><77>czenie albo wy<77><79>czenie silnika (w szerokim sensie)
|
||
OrdersClear(); // czyszczenie tabelki rozkaz<61>w, aby nic dalej nie robi<62>
|
||
if (NewValue1 == 0.0)
|
||
OrderNext(Release_engine); // wy<77><79>czy<7A> silnik (przygotowa<77> pojazd do jazdy)
|
||
else if (NewValue1 > 0.0)
|
||
OrderNext(Prepare_engine); // odpali<6C> silnik (wy<77><79>czy<7A> wszystko, co si<73> da)
|
||
// po za<7A><61>czeniu przejdzie do kolejnej komendy, po wy<77><79>czeniu na Wait_for_orders
|
||
}
|
||
else if (NewCommand == "Change_direction")
|
||
{
|
||
TOrders o = OrderList[OrderPos]; // co robi<62> przed zmian<61> kierunku
|
||
if (!iEngineActive)
|
||
OrderNext(Prepare_engine); // trzeba odpali<6C> silnik najpierw
|
||
if (NewValue1 == 0.0)
|
||
iDirectionOrder = -iDirection; // zmiana na przeciwny ni<6E> obecny
|
||
else if (NewLocation) // je<6A>li podane wsp<73><70>rz<72>dne eventu/kom<6F>rki ustawiaj<61>cej rozk<7A>ad
|
||
// (trainset nie podaje)
|
||
{
|
||
vector3 v = *NewLocation - pVehicle->GetPosition(); // wektor do punktu steruj<75>cego
|
||
vector3 d = pVehicle->VectorFront(); // wektor wskazuj<75>cy prz<72>d
|
||
iDirectionOrder = ((v.x * d.x + v.z * d.z) * NewValue1 > 0) ?
|
||
1 :
|
||
-1; // do przodu, gdy iloczyn skalarny i pr<70>dko<6B><6F> dodatnie
|
||
// iDirectionOrder=1; else if (NewValue1<0.0) iDirectionOrder=-1;
|
||
}
|
||
if (iDirectionOrder != iDirection)
|
||
OrderNext(Change_direction); // zadanie komendy do wykonania
|
||
if (o >= Shunt) // je<6A>li jazda manewrowa albo poci<63>gowa
|
||
OrderNext(o); // to samo robi<62> po zmianie
|
||
else if (!o) // je<6A>li wcze<7A>niej by<62>o czekanie
|
||
OrderNext(Shunt); // to dalej jazda manewrowa
|
||
if (mvOccupied->Vel >= 1.0) // je<6A>li jedzie
|
||
iDrivigFlags &= ~moveStartHorn; // to bez tr<74>bienia po ruszeniu z zatrzymania
|
||
// Change_direction wykona si<73> samo i nast<73>pnie przejdzie do kolejnej komendy
|
||
}
|
||
else if (NewCommand == "Obey_train")
|
||
{
|
||
if (!iEngineActive)
|
||
OrderNext(Prepare_engine); // trzeba odpali<6C> silnik najpierw
|
||
OrderNext(Obey_train);
|
||
// if (NewValue1>0) TrainNumber=floor(NewValue1); //i co potem ???
|
||
OrderCheck(); // je<6A>li jazda poci<63>gowa teraz, to wykona<6E> niezb<7A>dne operacje
|
||
}
|
||
else if (NewCommand == "Shunt")
|
||
{ // NewValue1 - ilo<6C><6F> wagon<6F>w (-1=wszystkie); NewValue2: 0=odczep, 1..63=do<64><6F>cz, -1=bez zmian
|
||
//-3,-y - pod<6F><64>czy<7A> do ca<63>ego stoj<6F>cego sk<73>adu (sprz<72>giem y>=1), zmieni<6E> kierunek i czeka<6B> w
|
||
// trybie poci<63>gowym
|
||
//-2,-y - pod<6F><64>czy<7A> do ca<63>ego stoj<6F>cego sk<73>adu (sprz<72>giem y>=1), zmieni<6E> kierunek i czeka<6B>
|
||
//-2, y - pod<6F><64>czy<7A> do ca<63>ego stoj<6F>cego sk<73>adu (sprz<72>giem y>=1) i czeka<6B>
|
||
//-1,-y - pod<6F><64>czy<7A> do ca<63>ego stoj<6F>cego sk<73>adu (sprz<72>giem y>=1) i jecha<68> w powrotn<74> stron<6F>
|
||
//-1, y - pod<6F><64>czy<7A> do ca<63>ego stoj<6F>cego sk<73>adu (sprz<72>giem y>=1) i jecha<68> dalej
|
||
//-1, 0 - tryb manewrowy bez zmian (odczepianie z pozostawieniem wagon<6F>w nie ma sensu)
|
||
// 0, 0 - odczepienie lokomotywy
|
||
// 1,-y - pod<6F><64>czy<7A> si<73> do sk<73>adu (sprz<72>giem y>=1), a nast<73>pnie odczepi<70> i zabra<72> (x)
|
||
// wagon<6F>w
|
||
// 1, 0 - odczepienie lokomotywy z jednym wagonem
|
||
iDrivigFlags &= ~moveStopHere; // podje<6A>anie do semafor<6F>w zezwolone
|
||
if (!iEngineActive)
|
||
OrderNext(Prepare_engine); // trzeba odpali<6C> silnik najpierw
|
||
if (NewValue2 != 0) // je<6A>li podany jest sprz<72>g
|
||
{
|
||
iCoupler = floor(fabs(NewValue2)); // jakim sprz<72>giem
|
||
OrderNext(Connect); // najpierw po<70><6F>cz pojazdy
|
||
if (NewValue1 >= 0.0) // je<6A>li ilo<6C><6F> wagon<6F>w inna ni<6E> wszystkie
|
||
{ // to po podpi<70>ciu nale<6C>y si<73> odczepi<70>
|
||
iDirectionOrder = -iDirection; // zmiana na ci<63>gni<6E>cie
|
||
OrderPush(Change_direction); // najpierw zmie<69> kierunek, bo odczepiamy z ty<74>u
|
||
OrderPush(Disconnect); // a odczep ju<6A> po zmianie kierunku
|
||
}
|
||
else if (NewValue2 < 0.0) // je<6A>li wszystkie, a sprz<72>g ujemny, to tylko zmiana kierunku
|
||
// po podczepieniu
|
||
{ // np. Shunt -1 -3
|
||
iDirectionOrder = -iDirection; // jak si<73> podczepi, to jazda w przeciwn<77> stron<6F>
|
||
OrderNext(Change_direction);
|
||
}
|
||
WaitingTime =
|
||
0.0; // nie ma co dalej czeka<6B>, mo<6D>na zatr<74>bi<62> i jecha<68>, chyba <20>e ju<6A> jedzie
|
||
}
|
||
else // if (NewValue2==0.0) //zerowy sprz<72>g
|
||
if (NewValue1 >= 0.0) // je<6A>li ilo<6C><6F> wagon<6F>w inna ni<6E> wszystkie
|
||
{ // b<>dzie odczepianie, ale je<6A>li wagony s<> z przodu, to trzeba najpierw zmieni<6E> kierunek
|
||
if ((mvOccupied->Couplers[mvOccupied->DirAbsolute > 0 ? 1 : 0].CouplingFlag ==
|
||
0) ? // z ty<74>u nic
|
||
(mvOccupied->Couplers[mvOccupied->DirAbsolute > 0 ? 0 : 1].CouplingFlag > 0) :
|
||
false) // a z przodu sk<73>ad
|
||
{
|
||
iDirectionOrder = -iDirection; // zmiana na ci<63>gni<6E>cie
|
||
OrderNext(Change_direction); // najpierw zmie<69> kierunek (zast<73>pi Disconnect)
|
||
OrderPush(Disconnect); // a odczep ju<6A> po zmianie kierunku
|
||
}
|
||
else if (mvOccupied->Couplers[mvOccupied->DirAbsolute > 0 ? 1 : 0].CouplingFlag >
|
||
0) // z ty<74>u co<63>
|
||
OrderNext(Disconnect); // jak ci<63>gnie, to tylko odczep (NewValue1) wagon<6F>w
|
||
WaitingTime =
|
||
0.0; // nie ma co dalej czeka<6B>, mo<6D>na zatr<74>bi<62> i jecha<68>, chyba <20>e ju<6A> jedzie
|
||
}
|
||
if (NewValue1 == -1.0)
|
||
{
|
||
iDrivigFlags &= ~moveStopHere; // ma jecha<68>
|
||
WaitingTime = 0.0; // nie ma co dalej czeka<6B>, mo<6D>na zatr<74>bi<62> i jecha<68>
|
||
}
|
||
if (NewValue1 < -1.5) // je<6A>li -2/-3, czyli czekanie z ruszeniem na sygna<6E>
|
||
iDrivigFlags |= moveStopHere; // nie podje<6A>d<EFBFBD>a<EFBFBD> do semafora, je<6A>li droga nie jest wolna
|
||
// (nie dotyczy Connect)
|
||
if (NewValue1 < -2.5) // je<6A>li
|
||
OrderNext(Obey_train); // to potem jazda poci<63>gowa
|
||
else
|
||
OrderNext(Shunt); // to potem manewruj dalej
|
||
CheckVehicles(); // sprawdzi<7A> <20>wiat<61>a
|
||
// if ((iVehicleCount>=0)&&(NewValue1<0)) WriteLog("Skasowano ilos<6F> wagon<6F>w w Shunt!");
|
||
if (NewValue1 != iVehicleCount)
|
||
iVehicleCount = floor(NewValue1); // i co potem ? - trzeba zaprogramowac odczepianie
|
||
/*
|
||
if (NewValue1!=-1.0)
|
||
if (NewValue2!=0.0)
|
||
|
||
if (VelDesired==0)
|
||
SetVelocity(20,0); //to niech jedzie
|
||
*/
|
||
}
|
||
else if (NewCommand == "Jump_to_first_order")
|
||
JumpToFirstOrder();
|
||
else if (NewCommand == "Jump_to_order")
|
||
{
|
||
if (NewValue1 == -1.0)
|
||
JumpToNextOrder();
|
||
else if ((NewValue1 >= 0) && (NewValue1 < maxorders))
|
||
{
|
||
OrderPos = floor(NewValue1);
|
||
if (!OrderPos)
|
||
OrderPos = 1; // zgodno<6E><6F> wstecz: dopiero pierwsza uruchamia
|
||
#if LOGORDERS
|
||
WriteLog("--> Jump_to_order");
|
||
OrdersDump();
|
||
#endif
|
||
}
|
||
/*
|
||
if (WriteLogFlag)
|
||
{
|
||
append(AIlogFile);
|
||
writeln(AILogFile,ElapsedTime:5:2," - new order: ",Order2Str( OrderList[OrderPos])," @
|
||
",OrderPos);
|
||
close(AILogFile);
|
||
}
|
||
*/
|
||
}
|
||
/* //ta komenda jest teraz skanowana, wi<77>c wysy<73>anie jej eventem nie ma sensu
|
||
else if (NewCommand=="OutsideStation") //wskaznik W5
|
||
{
|
||
if (OrderList[OrderPos]==Obey_train)
|
||
SetVelocity(NewValue1,NewValue2,stopOut); //koniec stacji - predkosc szlakowa
|
||
else //manewry - zawracaj
|
||
{
|
||
iDirectionOrder=-iDirection; //zmiana na przeciwny ni<6E> obecny
|
||
OrderNext(Change_direction); //zmiana kierunku
|
||
OrderNext(Shunt); //a dalej manewry
|
||
iDrivigFlags&=~moveStartHorn; //bez tr<74>bienia po zatrzymaniu
|
||
}
|
||
}
|
||
*/
|
||
else if (NewCommand == "Warning_signal")
|
||
{
|
||
if (AIControllFlag) // poni<6E>sza komenda nie jest wykonywana przez u<>ytkownika
|
||
if (NewValue1 > 0)
|
||
{
|
||
fWarningDuration = NewValue1; // czas tr<74>bienia
|
||
mvOccupied->WarningSignal = (NewValue2 > 1) ? 2 : 1; // wysoko<6B><6F> tonu
|
||
}
|
||
}
|
||
else if (NewCommand == "Radio_channel")
|
||
{ // wyb<79>r kana<6E>u radiowego (kt<6B>rego powinien u<>ywa<77> AI, r<>czny maszynista musi go ustawi<77> sam)
|
||
if (NewValue1 >= 0) // warto<74>ci ujemne s<> zarezerwowane, -1 = nie zmienia<69> kana<6E>u
|
||
{
|
||
iRadioChannel = NewValue1;
|
||
if (iGuardRadio)
|
||
iGuardRadio = iRadioChannel; // kierownikowi te<74> zmieni<6E>
|
||
}
|
||
// NewValue2 mo<6D>e zawiera<72> dodatkowo oczekiwany kod odpowiedzi, np. dla W29 "nawi<77>za<7A>
|
||
// <20><>czno<6E><6F> radiow<6F> z dy<64>urnym ruchu odcinkowym"
|
||
}
|
||
else
|
||
return false; // nierozpoznana - wys<79>a<EFBFBD> bezpo<70>rednio do pojazdu
|
||
return true; // komenda zosta<74>a przetworzona
|
||
};
|
||
|
||
void TController::PhysicsLog()
|
||
{ // zapis logu - na razie tylko wypisanie parametr<74>w
|
||
if (LogFile.is_open())
|
||
{
|
||
#if LOGPRESS == 0
|
||
LogFile << ElapsedTime << " " << fabs(11.31 * mvOccupied->WheelDiameter * mvOccupied->nrot)
|
||
<< " ";
|
||
LogFile << mvControlling->AccS << " " << mvOccupied->Couplers[1].Dist << " "
|
||
<< mvOccupied->Couplers[1].CForce << " ";
|
||
LogFile << mvOccupied->Ft << " " << mvOccupied->Ff << " " << mvOccupied->Fb << " "
|
||
<< mvOccupied->BrakePress << " ";
|
||
LogFile << mvOccupied->PipePress << " " << mvControlling->Im << " "
|
||
<< int(mvControlling->MainCtrlPos) << " ";
|
||
LogFile << int(mvControlling->ScndCtrlPos) << " " << int(mvOccupied->BrakeCtrlPos)
|
||
<< " " << int(mvOccupied->LocalBrakePos) << " ";
|
||
LogFile << int(mvControlling->ActiveDir) << " " << mvOccupied->CommandIn.Command.c_str()
|
||
<< " " << mvOccupied->CommandIn.Value1 << " ";
|
||
LogFile << mvOccupied->CommandIn.Value2 << " " << int(mvControlling->SecuritySystem.Status)
|
||
<< " " << int(mvControlling->SlippingWheels) << "\r\n";
|
||
#endif
|
||
#if LOGPRESS == 1
|
||
LogFile << ElapsedTime << "\t" << fabs(11.31 * mvOccupied->WheelDiameter * mvOccupied->nrot)
|
||
<< "\t";
|
||
LogFile << Controlling->AccS << "\t";
|
||
LogFile << mvOccupied->PipePress << "\t" << mvOccupied->CntrlPipePress << "\t"
|
||
<< mvOccupied->BrakePress << "\t";
|
||
LogFile << mvOccupied->Volume << "\t" << mvOccupied->Hamulec->GetCRP() << "\n";
|
||
#endif
|
||
LogFile.flush();
|
||
}
|
||
};
|
||
|
||
bool TController::UpdateSituation(double dt)
|
||
{ // uruchamia<69> przynajmniej raz na sekund<6E>
|
||
if ((iDrivigFlags & movePrimary) == 0)
|
||
return true; // pasywny nic nie robi
|
||
double AbsAccS;
|
||
// double VelReduced; //o ile km/h mo<6D>e przekroczy<7A> dozwolon<6F> pr<70>dko<6B><6F> bez hamowania
|
||
bool UpdateOK = false;
|
||
if (AIControllFlag)
|
||
{ // yb: zeby EP nie musial sie bawic z ciesnieniem w PG
|
||
// if (mvOccupied->BrakeSystem==ElectroPneumatic)
|
||
// mvOccupied->PipePress=0.5; //yB: w SPKS s<> poprawnie zrobione pozycje
|
||
if (mvControlling->SlippingWheels)
|
||
{
|
||
mvControlling->SandDoseOn(); // piasku!
|
||
// Controlling->SlippingWheels=false; //a to tu nie ma sensu, flaga u<>ywana w dalszej
|
||
// cz<63><7A>ci
|
||
}
|
||
}
|
||
// ABu-160305 testowanie gotowo<77>ci do jazdy
|
||
// Ra: przeniesione z DynObj, sk<73>ad u<>ytkownika te<74> jest testowany, <20>eby mu przekaza<7A>, <20>e ma
|
||
// odhamowa<77>
|
||
Ready = true; // wst<73>pnie gotowy
|
||
fReady = 0.0; // za<7A>o<EFBFBD>enie, <20>e odhamowany
|
||
fAccGravity = 0.0; // przyspieszenie wynikaj<61>ce z pochylenia
|
||
double dy; // sk<73>adowa styczna grawitacji, w przedziale <0,1>
|
||
TDynamicObject *p = pVehicles[0]; // pojazd na czole sk<73>adu
|
||
while (p)
|
||
{ // sprawdzenie odhamowania wszystkich po<70><6F>czonych pojazd<7A>w
|
||
if (Ready) // bo jak co<63> nie odhamowane, to dalej nie ma co sprawdza<7A>
|
||
// if (p->MoverParameters->BrakePress>=0.03*p->MoverParameters->MaxBrakePress)
|
||
if (p->MoverParameters->BrakePress >= 0.4) // wg UIC okre<72>lone sztywno na 0.04
|
||
{
|
||
Ready = false; // nie gotowy
|
||
// Ra: odlu<6C>nianie prze<7A>adowanych lokomotyw, ci<63>gni<6E>tych na zimno - prowizorka...
|
||
if (AIControllFlag) // sk<73>ad jak dot<6F>d by<62> wyluzowany
|
||
{
|
||
if (mvOccupied->BrakeCtrlPos == 0) // jest pozycja jazdy
|
||
if ((p->MoverParameters->PipePress - 5.0) >
|
||
-0.1) // je<6A>li ci<63>nienie jak dla jazdy
|
||
if (p->MoverParameters->Hamulec->GetCRP() >
|
||
p->MoverParameters->PipePress + 0.12) // za du<64>o w zbiorniku
|
||
p->MoverParameters->BrakeReleaser(1); // indywidualne luzowanko
|
||
if (p->MoverParameters->Power > 0.01) // je<6A>li ma silnik
|
||
if (p->MoverParameters->FuseFlag) // wywalony nadmiarowy
|
||
Need_TryAgain = true; // reset jak przy wywaleniu nadmiarowego
|
||
}
|
||
}
|
||
if (fReady < p->MoverParameters->BrakePress)
|
||
fReady = p->MoverParameters->BrakePress; // szukanie najbardziej zahamowanego
|
||
if ((dy = p->VectorFront().y) != 0.0) // istotne tylko dla pojazd<7A>w na pochyleniu
|
||
fAccGravity -= p->DirectionGet() * p->MoverParameters->TotalMassxg *
|
||
dy; // ci<63><69>ar razy sk<73>adowa styczna grawitacji
|
||
p = p->Next(); // pojazd pod<6F><64>czony z ty<74>u (patrz<72>c od czo<7A>a)
|
||
}
|
||
if (iDirection)
|
||
fAccGravity /=
|
||
iDirection *
|
||
fMass; // si<73><69> generuj<75> pojazdy na pochyleniu ale dzia<69>a ona ca<63>o<EFBFBD><6F> sk<73>adu, wi<77>c a=F/m
|
||
if (!Ready) // v367: je<6A>li wg powy<77>szych warunk<6E>w sk<73>ad nie jest odhamowany
|
||
if (fAccGravity < -0.05) // je<6A>li ma pod g<>r<EFBFBD> na tyle, by si<73> stoczy<7A>
|
||
// if (mvOccupied->BrakePress<0.08) //to wystarczy, <20>e zadzia<69>aj<61> liniowe (nie ma ich
|
||
// jeszcze!!!)
|
||
if (fReady < 0.8) // delikatniejszy warunek, obejmuje wszystkie wagony
|
||
Ready = true; //<2F>eby uzna<6E> za odhamowany
|
||
HelpMeFlag = false;
|
||
// Winger 020304
|
||
if (AIControllFlag)
|
||
{
|
||
if (mvControlling->EnginePowerSource.SourceType == CurrentCollector)
|
||
{
|
||
if (mvOccupied->ScndPipePress > 4.3) // gdy g<><67>wna spr<70><72>arka bezpiecznie nabije
|
||
// ci<63>nienie
|
||
mvControlling->bPantKurek3 =
|
||
true; // to mo<6D>na przestawi<77> kurek na zasilanie pantograf<61>w z g<><67>wnej pneumatyki
|
||
fVoltage =
|
||
0.5 * (fVoltage +
|
||
fabs(mvControlling->RunningTraction.TractionVoltage)); // u<>rednione napi<70>cie
|
||
// sieci: przy spadku
|
||
// poni<6E>ej warto<74>ci
|
||
// minimalnej op<6F><70>ni<6E>
|
||
// rozruch o losowy
|
||
// czas
|
||
if (fVoltage < mvControlling->EnginePowerSource.CollectorParameters
|
||
.MinV) // gdy roz<6F><7A>czenie WS z powodu niskiego napi<70>cia
|
||
if (fActionTime >= 0) // je<6A>li czas oczekiwania nie zosta<74> ustawiony
|
||
fActionTime =
|
||
-2 - random(10); // losowy czas oczekiwania przed ponownym za<7A><61>czeniem jazdy
|
||
}
|
||
if (mvOccupied->Vel > 0.0)
|
||
{ // je<6A>eli jedzie
|
||
if (iDrivigFlags & moveDoorOpened) // je<6A>li drzwi otwarte
|
||
if (mvOccupied->Vel > 1.0) // nie zamyka<6B> drzwi przy drganiach, bo zatrzymanie na W4
|
||
// akceptuje niewielkie pr<70>dko<6B>ci
|
||
Doors(false);
|
||
// przy prowadzeniu samochodu trzeba ka<6B>d<EFBFBD> o<> odsuwa<77> oddzielnie, inaczej kicha wychodzi
|
||
if (mvOccupied->CategoryFlag & 2) // je<6A>li samoch<63>d
|
||
// if (fabs(mvOccupied->OffsetTrackH)<mvOccupied->Dim.W) //Ra: szeroko<6B><6F> drogi tu
|
||
// powinna by<62>?
|
||
if (!mvOccupied->ChangeOffsetH(-0.01 * mvOccupied->Vel * dt)) // ruch w poprzek
|
||
// drogi
|
||
mvOccupied->ChangeOffsetH(0.01 * mvOccupied->Vel *
|
||
dt); // Ra: co to mia<69>o by<62>, to nie wiem
|
||
if (mvControlling->EnginePowerSource.SourceType == CurrentCollector)
|
||
{
|
||
if ((fOverhead2 >= 0.0) || iOverheadZero)
|
||
{ // je<6A>li jazda bezpr<70>dowa albo z opuszczonym pantografem
|
||
while (DecSpeed(true))
|
||
; // zerowanie nap<61>du
|
||
}
|
||
if ((fOverhead2 > 0.0) || iOverheadDown)
|
||
{ // jazda z opuszczonymi pantografami
|
||
mvControlling->PantFront(false);
|
||
mvControlling->PantRear(false);
|
||
}
|
||
else
|
||
{ // je<6A>li nie trzeba opuszcza<7A> pantograf<61>w
|
||
if (iDirection >= 0) // jak jedzie w kierunku sprz<72>gu 0
|
||
mvControlling->PantRear(true); // jazda na tylnym
|
||
else
|
||
mvControlling->PantFront(true);
|
||
}
|
||
if (mvOccupied->Vel > 10) // opuszczenie przedniego po rozp<7A>dzeniu si<73>
|
||
{
|
||
if (mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo >
|
||
1) // o ile jest wi<77>cej ni<6E> jeden
|
||
if (iDirection >= 0) // jak jedzie w kierunku sprz<72>gu 0
|
||
{ // poczeka<6B> na podniesienie tylnego
|
||
if (mvControlling->PantRearVolt !=
|
||
0.0) // czy jest napi<70>cie zasilaj<61>ce na tylnym?
|
||
mvControlling->PantFront(false); // opuszcza od sprz<72>gu 0
|
||
}
|
||
else
|
||
{ // poczeka<6B> na podniesienie przedniego
|
||
if (mvControlling->PantFrontVolt !=
|
||
0.0) // czy jest napi<70>cie zasilaj<61>ce na przednim?
|
||
mvControlling->PantRear(false); // opuszcza od sprz<72>gu 1
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (iDrivigFlags & moveStartHornNow) // czy ma zatr<74>bi<62> przed ruszeniem?
|
||
if (Ready) // got<6F>w do jazdy
|
||
if (iEngineActive) // jeszcze si<73> odpali<6C> musi
|
||
if (fStopTime >= 0) // i nie musi czeka<6B>
|
||
{ // uruchomienie tr<74>bienia
|
||
fWarningDuration = 0.3; // czas tr<74>bienia
|
||
// if (AIControllFlag) //jak siedzi krasnoludek, to w<><77>czy tr<74>bienie
|
||
mvOccupied->WarningSignal =
|
||
pVehicle->iHornWarning; // wysoko<6B><6F> tonu (2=wysoki)
|
||
iDrivigFlags |= moveStartHornDone; // nie tr<74>bi<62> a<> do ruszenia
|
||
iDrivigFlags &= ~moveStartHornNow; // tr<74>bienie zosta<74>o zorganizowane
|
||
}
|
||
}
|
||
ElapsedTime += dt;
|
||
WaitingTime += dt;
|
||
fBrakeTime -=
|
||
dt; // wpisana warto<74><6F> jest zmniejszana do 0, gdy ujemna nale<6C>y zmieni<6E> nastaw<61> hamulca
|
||
fStopTime += dt; // zliczanie czasu postoju, nie ruszy dop<6F>ki ujemne
|
||
fActionTime += dt; // czas u<>ywany przy regulacji pr<70>dko<6B>ci i zamykaniu drzwi
|
||
if (WriteLogFlag)
|
||
{
|
||
if (LastUpdatedTime > deltalog)
|
||
{ // zapis do pliku DAT
|
||
PhysicsLog();
|
||
if (fabs(mvOccupied->V) > 0.1) // Ra: [m/s]
|
||
deltalog = 0.05; // 0.2;
|
||
else
|
||
deltalog = 0.05; // 1.0;
|
||
LastUpdatedTime = 0.0;
|
||
}
|
||
else
|
||
LastUpdatedTime = LastUpdatedTime + dt;
|
||
}
|
||
// Ra: skanowanie r<>wnie<69> dla prowadzonego r<>cznie, aby podpowiedzie<69> pr<70>dko<6B><6F>
|
||
if ((LastReactionTime > Min0R(ReactionTime, 2.0)))
|
||
{
|
||
// Ra: nie wiem czemu ReactionTime potrafi dosta<74> 12 sekund, to jest przegi<67>cie, bo prze<7A>yna
|
||
// ST<53>J
|
||
// yB: ot<6F><74> jest to jedna trzecia czasu nape<70>niania na towarowym; mo<6D>e si<73> przyda<64> przy
|
||
// wdra<72>aniu hamowania, <20>eby nie rusza<7A>o kranem jak g<>upie
|
||
// Ra: ale nie mo<6D>e si<73> budzi<7A> co p<><70> minuty, bo prze<7A>yna semafory
|
||
// Ra: trzeba by tak:
|
||
// 1. Ustali<6C> istotn<74> odleg<65>o<EFBFBD><6F> zainteresowania (np. 3<>droga hamowania z V.max).
|
||
fBrakeDist = fDriverBraking * mvOccupied->Vel *
|
||
(40.0 + mvOccupied->Vel); // przybli<6C>ona droga hamowania
|
||
// dla hamowania -0.2 [m/ss] droga wynosi 0.389*Vel*Vel [km/h], czyli 600m dla 40km/h, 3.8km
|
||
// dla 100km/h i 9.8km dla 160km/h
|
||
// dla hamowania -0.4 [m/ss] droga wynosi 0.096*Vel*Vel [km/h], czyli 150m dla 40km/h, 1.0km
|
||
// dla 100km/h i 2.5km dla 160km/h
|
||
// og<6F>lnie droga hamowania przy sta<74>ym op<6F><70>nieniu to Vel*Vel/(3.6*3.6*a) [m]
|
||
// fBrakeDist powinno by<62> wyznaczane dla danego sk<73>adu za pomoc<6F> sieci neuronowych, w
|
||
// zale<6C>no<6E>ci od pr<70>dko<6B>ci i si<73>y (ci<63>nienia) hamowania
|
||
// nast<73>pnie w drug<75> stron<6F>, z drogi hamowania i chwilowej pr<70>dko<6B>ci powinno by<62> wyznaczane
|
||
// zalecane ci<63>nienie
|
||
if (fMass > 1000000.0)
|
||
fBrakeDist *= 2.0; // korekta dla ci<63><69>kich, bo prze<7A>ynaj<61> - da to co<63>?
|
||
if (mvOccupied->BrakeDelayFlag == bdelay_G)
|
||
fBrakeDist = fBrakeDist + 2 * mvOccupied->Vel; // dla nastawienia G
|
||
// koniecznie nale<6C>y wyd<79>u<EFBFBD>y<EFBFBD> drog<6F> na czas reakcji
|
||
// double scanmax=(mvOccupied->Vel>0.0)?3*fDriverDist+fBrakeDist:10.0*fDriverDist;
|
||
double scanmax = (mvOccupied->Vel > 5.0) ?
|
||
400 + fBrakeDist :
|
||
30.0 * fDriverDist; // 1500m dla stoj<6F>cych poci<63>g<EFBFBD>w; Ra 2015-01: przy
|
||
//double scanmax = Max0R(400 + fBrakeDist, 1500);
|
||
// d<>u<EFBFBD>szej drodze skanowania AI je<6A>dzi spokojniej
|
||
// 2. Sprawdzi<7A>, czy tabelka pokrywa za<7A>o<EFBFBD>ony odcinek (nie musi, je<6A>li jest STOP).
|
||
// 3. Sprawdzi<7A>, czy trajektoria ruchu przechodzi przez zwrotnice - je<6A>li tak, to sprawdzi<7A>,
|
||
// czy stan si<73> nie zmieni<6E>.
|
||
// 4. Ewentualnie uzupe<70>ni<6E> tabelk<6C> informacjami o sygna<6E>ach i ograniczeniach, je<6A>li si<73>
|
||
// "zu<7A>y<EFBFBD>a".
|
||
TableCheck(scanmax); // wype<70>nianie tabelki i aktualizacja odleg<65>o<EFBFBD>ci
|
||
// 5. Sprawdzi<7A> stany sygnalizacji zapisanej w tabelce, wyznaczy<7A> pr<70>dko<6B>ci.
|
||
// 6. Z tabelki wyznaczy<7A> krytyczn<7A> odleg<65>o<EFBFBD><6F> i pr<70>dko<6B><6F> (najmniejsze przyspieszenie).
|
||
// 7. Je<4A>li jest inny pojazd z przodu, ewentualnie skorygowa<77> odleg<65>o<EFBFBD><6F> i pr<70>dko<6B><6F>.
|
||
// 8. Ustali<6C> cz<63>stotliwo<77><6F> <20>wiadomo<6D>ci AI (zatrzymanie precyzyjne - cz<63><7A>ciej, brak atrakcji
|
||
// - rzadziej).
|
||
if (AIControllFlag)
|
||
{ // tu bedzie logika sterowania
|
||
if (mvOccupied->CommandIn.Command != "")
|
||
if (!mvOccupied->RunInternalCommand()) // rozpoznaj komende bo lokomotywa jej nie
|
||
// rozpoznaje
|
||
RecognizeCommand(); // samo czyta komend<6E> wstawion<6F> do pojazdu?
|
||
if (mvOccupied->SecuritySystem.Status > 1) // jak zadzia<69>a<EFBFBD>o CA/SHP
|
||
if (!mvOccupied->SecuritySystemReset()) // to skasuj
|
||
// if
|
||
// ((TestFlag(mvOccupied->SecuritySystem.Status,s_ebrake))&&(mvOccupied->BrakeCtrlPos==0)&&(AccDesired>0.0))
|
||
if ((TestFlag(mvOccupied->SecuritySystem.Status, s_SHPebrake) ||
|
||
TestFlag(mvOccupied->SecuritySystem.Status, s_CAebrake)) &&
|
||
(mvOccupied->BrakeCtrlPos == 0) && (AccDesired > 0.0))
|
||
mvOccupied->BrakeLevelSet(
|
||
0); //!!! hm, mo<6D>e po prostu normalnie sterowa<77> hamulcem?
|
||
}
|
||
switch (OrderList[OrderPos])
|
||
{ // ustalenie pr<70>dko<6B>ci przy doczepianiu i odczepianiu, dystans<6E>w w pozosta<74>ych przypadkach
|
||
case Connect: // pod<6F><64>czanie do sk<73>adu
|
||
if (iDrivigFlags & moveConnect)
|
||
{ // je<6A>li stan<61><6E> ju<6A> blisko, unikaj<61>c zderzenia i mo<6D>na pr<70>bowa<77> pod<6F><64>czy<7A>
|
||
fMinProximityDist = -0.01;
|
||
fMaxProximityDist = 0.0; //[m] dojecha<68> maksymalnie
|
||
fVelPlus = 0.5; // dopuszczalne przekroczenie pr<70>dko<6B>ci na ograniczeniu bez
|
||
// hamowania
|
||
fVelMinus = 0.5; // margines pr<70>dko<6B>ci powoduj<75>cy za<7A><61>czenie nap<61>du
|
||
if (AIControllFlag)
|
||
{ // to robi tylko AI, wersj<73> dla cz<63>owieka trzeba dopiero zrobi<62>
|
||
// sprz<72>gi sprawdzamy w pierwszej kolejno<6E>ci, bo jak po<70><6F>czony, to koniec
|
||
bool ok; // true gdy si<73> pod<6F><64>czy (uzyskany sprz<72>g b<>dzie zgodny z <20><>danym)
|
||
if (pVehicles[0]->DirectionGet() > 0) // je<6A>li sprz<72>g 0
|
||
{ // sprz<72>g 0 - pr<70>ba podczepienia
|
||
if (pVehicles[0]->MoverParameters->Couplers[0].Connected) // je<6A>li jest co<63>
|
||
// wykryte (a
|
||
// chyba jest,
|
||
// nie?)
|
||
if (pVehicles[0]->MoverParameters->Attach(
|
||
0, 2, pVehicles[0]->MoverParameters->Couplers[0].Connected,
|
||
iCoupler))
|
||
{
|
||
// pVehicles[0]->dsbCouplerAttach->SetVolume(DSBVOLUME_MAX);
|
||
// pVehicles[0]->dsbCouplerAttach->Play(0,0,0);
|
||
}
|
||
// WriteLog("CoupleDist[0]="+AnsiString(pVehicles[0]->MoverParameters->Couplers[0].CoupleDist)+",
|
||
// Connected[0]="+AnsiString(pVehicles[0]->MoverParameters->Couplers[0].CouplingFlag));
|
||
ok = (pVehicles[0]->MoverParameters->Couplers[0].CouplingFlag ==
|
||
iCoupler); // uda<64>o si<73>? (mog<6F>o cz<63><7A>ciowo)
|
||
}
|
||
else // if (pVehicles[0]->MoverParameters->DirAbsolute<0) //je<6A>li sprz<72>g 1
|
||
{ // sprz<72>g 1 - pr<70>ba podczepienia
|
||
if (pVehicles[0]->MoverParameters->Couplers[1].Connected) // je<6A>li jest co<63>
|
||
// wykryte (a
|
||
// chyba jest,
|
||
// nie?)
|
||
if (pVehicles[0]->MoverParameters->Attach(
|
||
1, 2, pVehicles[0]->MoverParameters->Couplers[1].Connected,
|
||
iCoupler))
|
||
{
|
||
// pVehicles[0]->dsbCouplerAttach->SetVolume(DSBVOLUME_MAX);
|
||
// pVehicles[0]->dsbCouplerAttach->Play(0,0,0);
|
||
}
|
||
// WriteLog("CoupleDist[1]="+AnsiString(Controlling->Couplers[1].CoupleDist)+",
|
||
// Connected[0]="+AnsiString(Controlling->Couplers[1].CouplingFlag));
|
||
ok = (pVehicles[0]->MoverParameters->Couplers[1].CouplingFlag ==
|
||
iCoupler); // uda<64>o si<73>? (mog<6F>o cz<63><7A>ciowo)
|
||
}
|
||
if (ok)
|
||
{ // je<6A>eli zosta<74> pod<6F><64>czony
|
||
iCoupler = 0; // dalsza jazda manewrowa ju<6A> bez <20><>czenia
|
||
iDrivigFlags &= ~moveConnect; // zdj<64>cie flagi doczepiania
|
||
SetVelocity(0, 0, stopJoin); // wy<77><79>czy<7A> przyspieszanie
|
||
CheckVehicles(); // sprawdzi<7A> <20>wiat<61>a nowego sk<73>adu
|
||
JumpToNextOrder(); // wykonanie nast<73>pnej komendy
|
||
}
|
||
else
|
||
SetVelocity(2.0, 0.0); // jazda w ustawionym kierunku z pr<70>dko<6B>ci<63> 2 (18s)
|
||
} // if (AIControllFlag) //koniec zblokowania, bo by<62>a zmienna lokalna
|
||
/* //Ra 2014-02: lepiej tam, bo jak tam si<73> od<6F>wie<69>y sk<73>ad, to tu pVehicles[0]
|
||
b<>dzie czym<79> innym
|
||
else
|
||
{//je<6A>li cz<63>owiek ma pod<6F><64>czy<7A>, to czekamy na zmian<61> stanu sprz<72>g<EFBFBD>w na ko<6B>cach
|
||
dotychczasowego sk<73>adu
|
||
bool ok; //true gdy si<73> pod<6F><64>czy (uzyskany sprz<72>g b<>dzie zgodny z <20><>danym)
|
||
if (pVehicles[0]->DirectionGet()>0) //je<6A>li sprz<72>g 0
|
||
ok=(pVehicles[0]->MoverParameters->Couplers[0].CouplingFlag>0);
|
||
//==iCoupler); //uda<64>o si<73>? (mog<6F>o cz<63><7A>ciowo)
|
||
else //if (pVehicles[0]->MoverParameters->DirAbsolute<0) //je<6A>li sprz<72>g 1
|
||
ok=(pVehicles[0]->MoverParameters->Couplers[1].CouplingFlag>0);
|
||
//==iCoupler); //uda<64>o si<73>? (mog<6F>o cz<63><7A>ciowo)
|
||
if (ok)
|
||
{//je<6A>eli zosta<74> pod<6F><64>czony
|
||
iDrivigFlags&=~moveConnect; //zdj<64>cie flagi doczepiania
|
||
JumpToNextOrder(); //wykonanie nast<73>pnej komendy
|
||
}
|
||
}
|
||
*/
|
||
}
|
||
else
|
||
{ // jak daleko, to jazda jak dla Shunt na kolizj<7A>
|
||
fMinProximityDist = 0.0;
|
||
fMaxProximityDist = 5.0; //[m] w takim przedziale odleg<65>o<EFBFBD>ci powinien stan<61><6E>
|
||
fVelPlus = 2.0; // dopuszczalne przekroczenie pr<70>dko<6B>ci na ograniczeniu bez
|
||
// hamowania
|
||
fVelMinus = 1.0; // margines pr<70>dko<6B>ci powoduj<75>cy za<7A><61>czenie nap<61>du
|
||
// VelReduced=5; //[km/h]
|
||
// if (mvOccupied->Vel<0.5) //je<6A>li ju<6A> prawie stan<61><6E>
|
||
if (pVehicles[0]->fTrackBlock <=
|
||
20.0) // przy zderzeniu fTrackBlock nie jest miarodajne
|
||
iDrivigFlags |=
|
||
moveConnect; // pocz<63>tek podczepiania, z wy<77><79>czeniem sprawdzania fTrackBlock
|
||
}
|
||
break;
|
||
case Disconnect: // 20.07.03 - manewrowanie wagonami
|
||
fMinProximityDist = 1.0;
|
||
fMaxProximityDist = 10.0; //[m]
|
||
fVelPlus = 1.0; // dopuszczalne przekroczenie pr<70>dko<6B>ci na ograniczeniu bez hamowania
|
||
fVelMinus = 0.5; // margines pr<70>dko<6B>ci powoduj<75>cy za<7A><61>czenie nap<61>du
|
||
if (AIControllFlag)
|
||
{
|
||
if (iVehicleCount >= 0) // je<6A>li by<62>a podana ilo<6C><6F> wagon<6F>w
|
||
{
|
||
if (iDrivigFlags & movePress) // je<6A>li dociskanie w celu odczepienia
|
||
{ // 3. faza odczepiania.
|
||
SetVelocity(2, 0); // jazda w ustawionym kierunku z pr<70>dko<6B>ci<63> 2
|
||
if ((mvControlling->MainCtrlPos > 0) ||
|
||
(mvOccupied->BrakeSystem == ElectroPneumatic)) // je<6A>li jazda
|
||
{
|
||
// WriteLog("Odczepianie w kierunku
|
||
// "+AnsiString(mvOccupied->DirAbsolute));
|
||
TDynamicObject *p =
|
||
pVehicle; // pojazd do odczepienia, w (pVehicle) siedzi AI
|
||
int d; // numer sprz<72>gu, kt<6B>ry sprawdzamy albo odczepiamy
|
||
int n = iVehicleCount; // ile wagon<6F>w ma zosta<74>
|
||
do
|
||
{ // szukanie pojazdu do odczepienia
|
||
d = p->DirectionGet() > 0 ?
|
||
0 :
|
||
1; // numer sprz<72>gu od strony czo<7A>a sk<73>adu
|
||
// if (p->MoverParameters->Couplers[d].CouplerType==Articulated)
|
||
// //je<6A>li sprz<72>g typu w<>zek (za ma<6D>o)
|
||
if (p->MoverParameters->Couplers[d].CouplingFlag &
|
||
ctrain_depot) // je<6A>eli sprz<72>g zablokowany
|
||
// if (p->GetTrack()->) //a nie stoi na torze warsztatowym
|
||
// (ustali<6C> po czym pozna<6E> taki tor)
|
||
++n; // to liczymy cz<63>ony jako jeden
|
||
p->MoverParameters->BrakeReleaser(
|
||
1); // wyluzuj pojazd, aby da<64>o si<73> dopycha<68>
|
||
p->MoverParameters->BrakeLevelSet(
|
||
0); // hamulec na zero, aby nie hamowa<77>
|
||
if (n)
|
||
{ // je<6A>li jeszcze nie koniec
|
||
p = p->Prev(); // kolejny w stron<6F> czo<7A>a sk<73>adu (licz<63>c od
|
||
// ty<74>u), bo dociskamy
|
||
if (!p)
|
||
iVehicleCount = -2,
|
||
n = 0; // nie ma co dalej sprawdza<7A>, doczepianie zako<6B>czone
|
||
}
|
||
} while (n--);
|
||
if (p ? p->MoverParameters->Couplers[d].CouplingFlag == 0 : true)
|
||
iVehicleCount = -2; // odczepiono, co by<62>o do odczepienia
|
||
else if (!p->Dettach(d)) // zwraca mask<EFBFBD> bitow<EFBFBD> po<EFBFBD><EFBFBD>czenia; usuwa
|
||
// w<>asno<6E><6F> pojazd<7A>w
|
||
{ // tylko je<6A>li odepnie
|
||
// WriteLog("Odczepiony od strony ");
|
||
iVehicleCount = -2;
|
||
} // a jak nie, to dociska<6B> dalej
|
||
}
|
||
if (iVehicleCount >= 0) // zmieni si<73> po odczepieniu
|
||
if (!mvOccupied->DecLocalBrakeLevel(1))
|
||
{ // doci<63>nij sklad
|
||
// WriteLog("Dociskanie");
|
||
// mvOccupied->BrakeReleaser(); //wyluzuj lokomotyw<79>
|
||
// Ready=true; //zamiast sprawdzenia odhamowania ca<63>ego sk<73>adu
|
||
IncSpeed(); // dla (Ready)==false nie ruszy
|
||
}
|
||
}
|
||
if ((mvOccupied->Vel == 0.0) && !(iDrivigFlags & movePress))
|
||
{ // 2. faza odczepiania: zmie<69> kierunek na przeciwny i doci<63>nij
|
||
// za rad<61> yB ustawiamy pozycj<63> 3 kranu (ruszanie kranem w innych miejscach
|
||
// powino zosta<74> wy<77><79>czone)
|
||
// WriteLog("Zahamowanie sk<73>adu");
|
||
// while ((mvOccupied->BrakeCtrlPos>3)&&mvOccupied->DecBrakeLevel());
|
||
// while ((mvOccupied->BrakeCtrlPos<3)&&mvOccupied->IncBrakeLevel());
|
||
mvOccupied->BrakeLevelSet(mvOccupied->BrakeSystem == ElectroPneumatic ? 1 :
|
||
3);
|
||
double p = mvOccupied->BrakePressureActual
|
||
.PipePressureVal; // tu mo<6D>e by<62> 0 albo -1 nawet
|
||
if (p < 3.9)
|
||
p = 3.9; // TODO: zabezpieczenie przed dziwnymi CHK do czasu wyja<6A>nienia
|
||
// sensu 0 oraz -1 w tym miejscu
|
||
if (mvOccupied->BrakeSystem == ElectroPneumatic ?
|
||
mvOccupied->BrakePress > 2 :
|
||
mvOccupied->PipePress < p + 0.1)
|
||
{ // je<6A>li w miar<61> zosta<74> zahamowany (ci<63>nienie mniejsze ni<6E> podane na
|
||
// pozycji 3, zwyle 0.37)
|
||
if (mvOccupied->BrakeSystem == ElectroPneumatic)
|
||
mvOccupied->BrakeLevelSet(0); // wy<77><79>czenie EP, gdy wystarczy (mo<6D>e
|
||
// nie by<62> potrzebne, bo na pocz<63>tku
|
||
// jest)
|
||
// WriteLog("Luzowanie lokomotywy i zmiana kierunku");
|
||
mvOccupied->BrakeReleaser(1); // wyluzuj lokomotyw<79>; a ST45?
|
||
mvOccupied->DecLocalBrakeLevel(10); // zwolnienie hamulca
|
||
iDrivigFlags |= movePress; // nast<73>pnie b<>dzie dociskanie
|
||
DirectionForward(mvOccupied->ActiveDir <
|
||
0); // zmiana kierunku jazdy na przeciwny (dociskanie)
|
||
CheckVehicles(); // od razu zmieni<6E> <20>wiat<61>a (zgasi<73>) - bez tego si<73> nie
|
||
// odczepi
|
||
fStopTime = 0.0; // nie ma na co czeka<6B> z odczepianiem
|
||
}
|
||
}
|
||
} // odczepiania
|
||
else // to poni<6E>ej je<6A>li ilo<6C><6F> wagon<6F>w ujemna
|
||
if (iDrivigFlags & movePress)
|
||
{ // 4. faza odczepiania: zwolnij i zmie<69> kierunek
|
||
SetVelocity(0, 0, stopJoin); // wy<77><79>czy<7A> przyspieszanie
|
||
if (!DecSpeed()) // je<6A>li ju<6A> bardziej wy<77><79>czy<7A> si<73> nie da
|
||
{ // ponowna zmiana kierunku
|
||
// WriteLog("Ponowna zmiana kierunku");
|
||
DirectionForward(mvOccupied->ActiveDir <
|
||
0); // zmiana kierunku jazdy na w<>a<EFBFBD>ciwy
|
||
iDrivigFlags &= ~movePress; // koniec dociskania
|
||
JumpToNextOrder(); // zmieni <20>wiat<61>a
|
||
TableClear(); // skanowanie od nowa
|
||
iDrivigFlags &= ~moveStartHorn; // bez tr<74>bienia przed ruszeniem
|
||
SetVelocity(fShuntVelocity, fShuntVelocity); // ustawienie pr<70>dko<6B>ci jazdy
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case Shunt:
|
||
// na jak<61> odleglo<6C><6F> i z jak<61> predko<6B>ci<63> ma podjecha<68>
|
||
fMinProximityDist = 2.0;
|
||
fMaxProximityDist = 4.0; //[m]
|
||
fVelPlus = 2.0; // dopuszczalne przekroczenie pr<70>dko<6B>ci na ograniczeniu bez hamowania
|
||
fVelMinus = 3.0; // margines pr<70>dko<6B>ci powoduj<75>cy za<7A><61>czenie nap<61>du
|
||
if (fVelMinus > 0.1 * fShuntVelocity)
|
||
fVelMinus =
|
||
0.1 *
|
||
fShuntVelocity; // by<62>y problemy z jazd<7A> np. 3km/h podczas <20>adowania wagon<6F>w
|
||
break;
|
||
case Obey_train:
|
||
// na jaka odleglosc i z jaka predkoscia ma podjechac do przeszkody
|
||
if (mvOccupied->CategoryFlag & 1) // je<6A>li poci<63>g
|
||
{
|
||
fMinProximityDist = 10.0;
|
||
fMaxProximityDist =
|
||
(mvOccupied->Vel > 0.0) ?
|
||
20.0 :
|
||
50.0; //[m] jak stanie za daleko, to niech nie doci<63>ga paru metr<74>w
|
||
if (iDrivigFlags & moveLate)
|
||
{
|
||
fVelMinus = 1.0; // je<6A>li sp<73><70>niony, to gna
|
||
fVelPlus =
|
||
5.0; // dopuszczalne przekroczenie pr<70>dko<6B>ci na ograniczeniu bez hamowania
|
||
}
|
||
else
|
||
{ // gdy nie musi si<73> spr<70><72>a<EFBFBD>
|
||
fVelMinus =
|
||
int(0.05 * VelDesired); // margines pr<70>dko<6B>ci powoduj<75>cy za<7A><61>czenie nap<61>du
|
||
if (fVelMinus > 5.0)
|
||
fVelMinus = 5.0;
|
||
else if (fVelMinus < 1.0)
|
||
fVelMinus = 1.0; //<2F>eby nie rusza<7A> przy 0.1
|
||
fVelPlus = int(
|
||
0.5 +
|
||
0.05 * VelDesired); // normalnie dopuszczalne przekroczenie to 5% pr<70>dko<6B>ci
|
||
if (fVelPlus > 5.0)
|
||
fVelPlus = 5.0; // ale nie wi<77>cej ni<6E> 5km/h
|
||
}
|
||
}
|
||
else // samochod (sokista te<74>)
|
||
{
|
||
fMinProximityDist = 7.0;
|
||
fMaxProximityDist = 10.0; //[m]
|
||
fVelPlus =
|
||
10.0; // dopuszczalne przekroczenie pr<70>dko<6B>ci na ograniczeniu bez hamowania
|
||
fVelMinus = 2.0; // margines pr<70>dko<6B>ci powoduj<75>cy za<7A><61>czenie nap<61>du
|
||
}
|
||
// VelReduced=4; //[km/h]
|
||
break;
|
||
default:
|
||
fMinProximityDist = 0.01;
|
||
fMaxProximityDist = 2.0; //[m]
|
||
fVelPlus = 2.0; // dopuszczalne przekroczenie pr<70>dko<6B>ci na ograniczeniu bez hamowania
|
||
fVelMinus = 5.0; // margines pr<70>dko<6B>ci powoduj<75>cy za<7A><61>czenie nap<61>du
|
||
} // switch
|
||
switch (OrderList[OrderPos])
|
||
{ // co robi maszynista
|
||
case Prepare_engine: // odpala silnik
|
||
// if (AIControllFlag)
|
||
if (PrepareEngine()) // dla u<>ytkownika tylko sprawdza, czy uruchomi<6D>
|
||
{ // gotowy do drogi?
|
||
SetDriverPsyche();
|
||
// OrderList[OrderPos]:=Shunt; //Ra: to nie mo<6D>e tak by<62>, bo scenerie robi<62>
|
||
// Jump_to_first_order i przechodzi w manewrowy
|
||
JumpToNextOrder(); // w nast<73>pnym jest Shunt albo Obey_train, moze te<74> by<62>
|
||
// Change_direction, Connect albo Disconnect
|
||
// if OrderList[OrderPos]<>Wait_for_Orders)
|
||
// if BrakeSystem=Pneumatic) //napelnianie uderzeniowe na wstepie
|
||
// if BrakeSubsystem=Oerlikon)
|
||
// if (BrakeCtrlPos=0))
|
||
// DecBrakeLevel;
|
||
}
|
||
break;
|
||
case Release_engine:
|
||
if (ReleaseEngine()) // zdana maszyna?
|
||
JumpToNextOrder();
|
||
break;
|
||
case Jump_to_first_order:
|
||
if (OrderPos > 1)
|
||
OrderPos = 1; // w zerowym zawsze jest czekanie
|
||
else
|
||
++OrderPos;
|
||
#if LOGORDERS
|
||
WriteLog("--> Jump_to_first_order");
|
||
OrdersDump();
|
||
#endif
|
||
break;
|
||
case Wait_for_orders: // je<6A>li czeka, te<74> ma skanowa<77>, <20>eby odpali<6C> si<73> od semafora
|
||
/*
|
||
if ((mvOccupied->ActiveDir!=0))
|
||
{//je<6A>li jest wybrany kierunek jazdy, mo<6D>na ustali<6C> pr<70>dko<6B><6F> jazdy
|
||
VelDesired=fVelMax; //wst<73>pnie pr<70>dko<6B><6F> maksymalna dla pojazdu(-<2D>w), b<>dzie nast<73>pnie
|
||
ograniczana
|
||
SetDriverPsyche(); //ustawia AccPreferred (potrzebne tu?)
|
||
//Ra: odczyt (ActualProximityDist), (VelNext) i (AccPreferred) z tabelki pr<70>dkosci
|
||
AccDesired=AccPreferred; //AccPreferred wynika z osobowo<77>ci mechanika
|
||
VelNext=VelDesired; //maksymalna pr<70>dko<6B><6F> wynikaj<61>ca z innych czynnik<69>w ni<6E>
|
||
trajektoria ruchu
|
||
ActualProximityDist=scanmax; //funkcja Update() mo<6D>e pozostawi<77> warto<74>ci bez zmian
|
||
//hm, kiedy<64> semafory wysy<73>a<EFBFBD>y SetVelocity albo ShuntVelocity i ustaw<61>y tak VelSignal
|
||
- a teraz jak to zrobi<62>?
|
||
TCommandType
|
||
comm=TableUpdate(mvOccupied->Vel,VelDesired,ActualProximityDist,VelNext,AccDesired);
|
||
//szukanie optymalnych warto<74>ci
|
||
}
|
||
*/
|
||
// break;
|
||
case Shunt:
|
||
case Obey_train:
|
||
case Connect:
|
||
case Disconnect:
|
||
case Change_direction: // tryby wymagaj<61>ce jazdy
|
||
case Change_direction | Shunt: // zmiana kierunku podczas manewr<77>w
|
||
case Change_direction | Connect: // zmiana kierunku podczas pod<6F><64>czania
|
||
if (OrderList[OrderPos] != Obey_train) // spokojne manewry
|
||
{
|
||
VelSignal = Global::Min0RSpeed(VelSignal, 40); // je<6A>li manewry, to ograniczamy pr<70>dko<6B><6F>
|
||
if (AIControllFlag)
|
||
{ // to poni<6E>ej tylko dla AI
|
||
if (iVehicleCount >= 0) // je<6A>li jest co odczepi<70>
|
||
if (!(iDrivigFlags & movePress))
|
||
if (mvOccupied->Vel > 0.0)
|
||
if (!iCoupler) // je<6A>li nie ma wcze<7A>niej potrzeby podczepienia
|
||
{
|
||
SetVelocity(0, 0, stopJoin); // 1. faza odczepiania: zatrzymanie
|
||
// WriteLog("Zatrzymanie w celu odczepienia");
|
||
}
|
||
}
|
||
}
|
||
else
|
||
SetDriverPsyche(); // Ra: by<62>o w PrepareEngine(), potrzebne tu?
|
||
// no albo przypisujemy -WaitingExpireTime, albo por<6F>wnujemy z WaitingExpireTime
|
||
// if
|
||
// ((VelSignal==0.0)&&(WaitingTime>WaitingExpireTime)&&(mvOccupied->RunningTrack.Velmax!=0.0))
|
||
if (OrderList[OrderPos] &
|
||
(Shunt | Obey_train | Connect)) // odjecha<68> sam mo<6D>e tylko je<6A>li jest w trybie jazdy
|
||
{ // automatyczne ruszanie po odstaniu albo spod SBL
|
||
if ((VelSignal == 0.0) && (WaitingTime > 0.0) &&
|
||
(mvOccupied->RunningTrack.Velmax != 0.0))
|
||
{ // je<6A>li stoi, a up<75>yn<79><6E> czas oczekiwania i tor ma niezerow<6F> pr<70>dko<6B><6F>
|
||
/*
|
||
if (WriteLogFlag)
|
||
{
|
||
append(AIlogFile);
|
||
writeln(AILogFile,ElapsedTime:5:2,": ",Name," V=0 waiting time expired!
|
||
(",WaitingTime:4:1,")");
|
||
close(AILogFile);
|
||
}
|
||
*/
|
||
if ((OrderList[OrderPos] & (Obey_train | Shunt)) ?
|
||
(iDrivigFlags & moveStopHere) :
|
||
false)
|
||
WaitingTime = -WaitingExpireTime; // zakaz ruszania z miejsca bez otrzymania
|
||
// wolnej drogi
|
||
else if (mvOccupied->CategoryFlag & 1)
|
||
{ // je<6A>li poci<63>g
|
||
if (AIControllFlag)
|
||
{
|
||
PrepareEngine(); // zmieni ustawiony kierunek
|
||
SetVelocity(20, 20); // jak si<73> nasta<74>, to niech jedzie 20km/h
|
||
WaitingTime = 0.0;
|
||
fWarningDuration = 1.5; // a zatr<74>bi<62> troch<63>
|
||
mvOccupied->WarningSignal = 1;
|
||
}
|
||
else
|
||
SetVelocity(20, 20); // u<>ytkownikowi zezwalamy jecha<68>
|
||
}
|
||
else
|
||
{ // samoch<63>d ma sta<74>, a<> dostanie odjazd, chyba <20>e stoi przez kolizj<7A>
|
||
if (eStopReason == stopBlock)
|
||
if (pVehicles[0]->fTrackBlock > fDriverDist)
|
||
if (AIControllFlag)
|
||
{
|
||
PrepareEngine(); // zmieni ustawiony kierunek
|
||
SetVelocity(-1, -1); // jak si<73> nasta<74>, to niech jedzie
|
||
WaitingTime = 0.0;
|
||
}
|
||
else
|
||
SetVelocity(-1,
|
||
-1); // u<>ytkownikowi pozwalamy jecha<68> (samochodem?)
|
||
}
|
||
}
|
||
else if ((VelSignal == 0.0) && (VelNext > 0.0) && (mvOccupied->Vel < 1.0))
|
||
if (iCoupler ? true : (iDrivigFlags & moveStopHere) == 0) // Ra: tu jest co<63> nie
|
||
// tak, bo bez tego
|
||
// warunku rusza<7A>o w
|
||
// manewrowym !!!!
|
||
SetVelocity(VelNext, VelNext, stopSem); // omijanie SBL
|
||
} // koniec samoistnego odje<6A>d<EFBFBD>ania
|
||
if (AIControllFlag)
|
||
if ((HelpMeFlag) || (mvControlling->DamageFlag > 0))
|
||
{
|
||
HelpMeFlag = false;
|
||
/*
|
||
if (WriteLogFlag)
|
||
with Controlling do
|
||
{
|
||
append(AIlogFile);
|
||
writeln(AILogFile,ElapsedTime:5:2,": ",Name," HelpMe!
|
||
(",DamageFlag,")");
|
||
close(AILogFile);
|
||
}
|
||
*/
|
||
}
|
||
if (AIControllFlag)
|
||
if (OrderList[OrderPos] &
|
||
Change_direction) // mo<6D>e by<62> zmieszane z jeszcze jak<61><6B> komend<6E>
|
||
{ // sprobuj zmienic kierunek
|
||
SetVelocity(0, 0, stopDir); // najpierw trzeba si<73> zatrzyma<6D>
|
||
if (mvOccupied->Vel < 0.1)
|
||
{ // je<6A>li si<73> zatrzyma<6D>, to zmieniamy kierunek jazdy, a nawet kabin<69>/cz<63>on
|
||
Activation(); // ustawienie zadanego wcze<7A>niej kierunku i ewentualne
|
||
// przemieszczenie AI
|
||
PrepareEngine();
|
||
JumpToNextOrder(); // nast<73>pnie robimy, co jest do zrobienia (Shunt albo
|
||
// Obey_train)
|
||
if (OrderList[OrderPos] & (Shunt | Connect)) // je<6A>li dalej mamy manewry
|
||
if ((iDrivigFlags & moveStopHere) == 0) // o ile nie sta<74> w miejscu
|
||
{ // jecha<68> od razu w przeciwn<77> stron<6F> i nie tr<74>bi<62> z tego tytu<74>u
|
||
iDrivigFlags &= ~moveStartHorn; // bez tr<74>bienia przed ruszeniem
|
||
SetVelocity(fShuntVelocity, fShuntVelocity); // to od razu jedziemy
|
||
}
|
||
// iDrivigFlags|=moveStartHorn; //a p<><70>niej ju<6A> mo<6D>na tr<74>bi<62>
|
||
/*
|
||
if (WriteLogFlag)
|
||
{
|
||
append(AIlogFile);
|
||
writeln(AILogFile,ElapsedTime:5:2,": ",Name," Direction changed!");
|
||
close(AILogFile);
|
||
}
|
||
*/
|
||
}
|
||
// else
|
||
// VelSignal:=0.0; //na wszelki wypadek niech zahamuje
|
||
} // Change_direction (tylko dla AI)
|
||
// ustalanie zadanej predkosci
|
||
if (AIControllFlag) // je<6A>li prowadzi AI
|
||
if (!iEngineActive) // je<6A>li silnik nie odpalony, to pr<70>bowa<77> naprawi<77>
|
||
if (OrderList[OrderPos] & (Change_direction | Connect | Disconnect | Shunt |
|
||
Obey_train)) // je<6A>li co<63> ma robi<62>
|
||
PrepareEngine(); // to niech odpala do skutku
|
||
if (iDrivigFlags & moveActive) // je<6A>li mo<6D>e skanowa<77> sygna<6E>y i reagowa<77> na komendy
|
||
{ // je<6A>li jest wybrany kierunek jazdy, mo<6D>na ustali<6C> pr<70>dko<6B><6F> jazdy
|
||
// Ra: tu by jeszcze trzeba by<62>o wstawi<77> uzale<6C>nienie (VelDesired) od odleg<65>o<EFBFBD>ci od
|
||
// przeszkody
|
||
// no chyba <20>eby to uwzgldni<6E> ju<6A> w (ActualProximityDist)
|
||
VelDesired = fVelMax; // wst<73>pnie pr<70>dko<6B><6F> maksymalna dla pojazdu(-<2D>w), b<>dzie
|
||
// nast<73>pnie ograniczana
|
||
if (TrainParams) // je<6A>li ma rozk<7A>ad
|
||
if (TrainParams->TTVmax > 0.0) // i ograniczenie w rozk<7A>adzie
|
||
VelDesired = Global::Min0RSpeed(VelDesired,
|
||
TrainParams->TTVmax); // to nie przekracza<7A> rozkladowej
|
||
SetDriverPsyche(); // ustawia AccPreferred (potrzebne tu?)
|
||
// Ra: odczyt (ActualProximityDist), (VelNext) i (AccPreferred) z tabelki pr<70>dkosci
|
||
AccDesired = AccPreferred; // AccPreferred wynika z osobowo<77>ci mechanika
|
||
VelNext = VelDesired; // maksymalna pr<70>dko<6B><6F> wynikaj<61>ca z innych czynnik<69>w ni<6E>
|
||
// trajektoria ruchu
|
||
ActualProximityDist = scanmax; // funkcja Update() mo<6D>e pozostawi<77> warto<74>ci bez
|
||
// zmian
|
||
// hm, kiedy<64> semafory wysy<73>a<EFBFBD>y SetVelocity albo ShuntVelocity i ustaw<61>y tak
|
||
// VelSignal - a teraz jak to zrobi<62>?
|
||
TCommandType comm = TableUpdate(VelDesired, ActualProximityDist, VelNext,
|
||
AccDesired); // szukanie optymalnych warto<74>ci
|
||
// if (VelSignal!=VelDesired) //je<6A>eli pr<70>dko<6B><6F> zalecana jest inna (ale tryb te<74>
|
||
// mo<6D>e by<62> inny)
|
||
switch (comm)
|
||
{ // ustawienie VelSignal - troch<63> proteza = do przemy<6D>lenia
|
||
case cm_Ready: // W4 zezwoli<6C> na jazd<7A>
|
||
TableCheck(
|
||
scanmax); // ewentualne doskanowanie trasy za W4, kt<6B>ry zezwoli<6C> na jazd<7A>
|
||
TableUpdate(VelDesired, ActualProximityDist, VelNext,
|
||
AccDesired); // aktualizacja po skanowaniu
|
||
// if (comm!=cm_SetVelocity) //je<6A>li dalej jest kolejny W4, to ma zwr<77>ci<63>
|
||
// cm_SetVelocity
|
||
if (VelNext == 0.0)
|
||
break; // ale jak co<63> z przodu zamyka, to ma sta<74>
|
||
if (iDrivigFlags & moveStopCloser)
|
||
VelSignal = -1.0; // niech jedzie, jak W4 pu<70>ci<63>o - nie, ma czeka<6B> na
|
||
// sygna<6E> z sygnalizatora!
|
||
case cm_SetVelocity: // od wersji 357 semafor nie budzi wy<77><79>czonej lokomotywy
|
||
if (!(OrderList[OrderPos] &
|
||
~(Obey_train | Shunt))) // jedzie w dowolnym trybie albo Wait_for_orders
|
||
if (fabs(VelSignal) >=
|
||
1.0) // 0.1 nie wysy<73>a si<73> do samochodow, bo potem nie rusz<73>
|
||
PutCommand("SetVelocity", VelSignal, VelNext,
|
||
NULL); // komenda robi dodatkowe operacje
|
||
break;
|
||
case cm_ShuntVelocity: // od wersji 357 Tm nie budzi wy<77><79>czonej lokomotywy
|
||
if (!(OrderList[OrderPos] &
|
||
~(Obey_train | Shunt))) // jedzie w dowolnym trybie albo Wait_for_orders
|
||
PutCommand("ShuntVelocity", VelSignal, VelNext, NULL);
|
||
else if (iCoupler) // je<6A>li jedzie w celu po<70><6F>czenia
|
||
SetVelocity(VelSignal, VelNext);
|
||
break;
|
||
case cm_Command: // komenda z kom<6F>rki
|
||
if (!(OrderList[OrderPos] &
|
||
~(Obey_train | Shunt))) // jedzie w dowolnym trybie albo Wait_for_orders
|
||
if (mvOccupied->Vel < 0.1) // dopiero jak stanie
|
||
// iDrivigFlags|=moveStopHere moveStopCloser) //chyba <20>e stan<61><6E> za daleko
|
||
// (SU46 w WK staje za daleko)
|
||
{
|
||
PutCommand(eSignNext->CommandGet(), eSignNext->ValueGet(1),
|
||
eSignNext->ValueGet(2), NULL);
|
||
eSignNext->StopCommandSent(); // si<73> wykona<6E>o ju<6A>
|
||
}
|
||
break;
|
||
}
|
||
if (VelNext == 0.0)
|
||
if (!(OrderList[OrderPos] &
|
||
~(Shunt | Connect))) // jedzie w Shunt albo Connect, albo Wait_for_orders
|
||
{ // je<6A>eli wolnej drogi nie ma, a jest w trybie manewrowym albo oczekiwania
|
||
// if
|
||
// ((OrderList[OrderPos]&Connect)?pVehicles[0]->fTrackBlock>ActualProximityDist:true)
|
||
// //pomiar odleg<65>o<EFBFBD>ci nie dzia<69>a dobrze?
|
||
// w trybie Connect skanowa<77> do ty<74>u tylko je<6A>li przed kolejnym sygna<6E>em nie
|
||
// ma taboru do pod<6F><64>czenia
|
||
// Ra 2F1H: z tym (fTrackBlock) to nie jest najlepszy pomys<79>, bo lepiej by
|
||
// by<62>o por<6F>wna<6E> z odleg<65>o<EFBFBD>ci<63> od sygnalizatora z przodu
|
||
if ((OrderList[OrderPos] & Connect) ? (pVehicles[0]->fTrackBlock > 2000 || pVehicles[0]->fTrackBlock > FirstSemaphorDist) :
|
||
true)
|
||
if ((comm = BackwardScan()) != cm_Unknown) // je<6A>li w drug<75> mo<6D>na jecha<68>
|
||
{ // nale<6C>y sprawdza<7A> odleg<65>o<EFBFBD><6F> od znalezionego sygnalizatora,
|
||
// aby w przypadku pr<70>dko<6B>ci 0.1 wyci<63>gn<67><6E> najpierw sk<73>ad za
|
||
// sygnalizator
|
||
// i dopiero wtedy zmieni<6E> kierunek jazdy, oczekuj<75>c podania
|
||
// pr<70>dko<6B>ci >0.5
|
||
if (comm == cm_Command) // je<6A>li komenda Shunt
|
||
iDrivigFlags |=
|
||
moveStopHere; // to j<> odbierz bez przemieszczania si<73> (np.
|
||
// odczep wagony po dopchni<6E>ciu do ko<6B>ca toru)
|
||
iDirectionOrder = -iDirection; // zmiana kierunku jazdy
|
||
OrderList[OrderPos] = TOrders(OrderList[OrderPos] |
|
||
Change_direction); // zmiana kierunku
|
||
// bez psucia
|
||
// kolejnych komend
|
||
}
|
||
}
|
||
double vel = mvOccupied->Vel; // pr<70>dko<6B><6F> w kierunku jazdy
|
||
if (iDirection * mvOccupied->V < 0)
|
||
vel = -vel; // ujemna, gdy jedzie w przeciwn<77> stron<6F>, ni<6E> powinien
|
||
if (VelDesired < 0.0)
|
||
VelDesired = fVelMax; // bo VelDesired<0 oznacza pr<70>dko<6B><6F> maksymaln<6C>
|
||
// Ra: jazda na widoczno<6E><6F>
|
||
if (pVehicles[0]->fTrackBlock < 1000.0) // przy 300m sta<74> z zapami<6D>tan<61> kolizj<7A>
|
||
{ // Ra 2F3F: przy je<6A>dzie poci<63>gowej nie powinien doje<6A>d<EFBFBD>a<EFBFBD> do poprzedzaj<61>cego
|
||
// sk<73>adu
|
||
if ((mvOccupied->CategoryFlag & 1) ?
|
||
((OrderCurrentGet() & (Connect | Obey_train)) == Obey_train) :
|
||
false) // je<6A>li jeste<74>my poci<63>giem a jazda poci<63>gowa i nie <20>ci<63>ganie ze
|
||
// szlaku
|
||
{
|
||
pVehicles[0]->ABuScanObjects(pVehicles[0]->DirectionGet(),
|
||
1000.0); // skanowanie sprawdzaj<61>ce
|
||
// Ra 2F3F: i jest problem, jak droga za semaforem kieruje na jaki<6B> pojazd
|
||
// (np. w Skwarkach na ET22)
|
||
if (pVehicles[0]->fTrackBlock < 1000.0) // i je<6A>li nadal co<63> jest
|
||
if (VelNext != 0.0) // a nast<73>pny sygna<6E> zezwala na jazd<7A>
|
||
if (pVehicles[0]->fTrackBlock <
|
||
ActualProximityDist) // i jest bli<6C>ej (tu by trzeba by<62>o wstawi<77>
|
||
// odleg<65>o<EFBFBD><6F> do semafora, z pomini<6E>ciem SBL
|
||
VelDesired = 0.0; // to stoimy
|
||
}
|
||
else
|
||
pVehicles[0]->ABuScanObjects(pVehicles[0]->DirectionGet(),
|
||
300.0); // skanowanie sprawdzaj<61>ce
|
||
}
|
||
// if (mvOccupied->Vel>=0.1) //o ile jedziemy; jak stoimy to te<74> trzeba jako<6B>
|
||
// zatrzymywa<77>
|
||
if ((iDrivigFlags & moveConnect) == 0) // przy ko<6B>c<EFBFBD>wce pod<6F><64>czania nie hamowa<77>
|
||
{ // sprawdzenie jazdy na widoczno<6E><6F>
|
||
TCoupling *c =
|
||
pVehicles[0]->MoverParameters->Couplers +
|
||
(pVehicles[0]->DirectionGet() > 0 ? 0 : 1); // sprz<72>g z przodu sk<73>adu
|
||
if (c->Connected) // a mamy co<63> z przodu
|
||
if (c->CouplingFlag ==
|
||
0) // je<6A>li to co<63> jest pod<6F><64>czone sprz<72>giem wirtualnym
|
||
{ // wyliczanie optymalnego przyspieszenia do jazdy na widoczno<6E><6F>
|
||
double k = c->Connected->Vel; // pr<70>dko<6B><6F> pojazdu z przodu (zak<61>adaj<61>c,
|
||
// <20>e jedzie w t<> sam<61> stron<6F>!!!)
|
||
if (k < vel + 10) // por<6F>wnanie modu<64><75>w pr<70>dko<6B>ci [km/h]
|
||
{ // zatroszczy<7A> si<73> trzeba, je<6A>li tamten nie jedzie znacz<63>co szybciej
|
||
double d =
|
||
pVehicles[0]->fTrackBlock - 0.5 * vel -
|
||
fMaxProximityDist; // odleg<65>o<EFBFBD><6F> bezpieczna zale<6C>y od pr<70>dko<6B>ci
|
||
if (d < 0) // je<6A>li odleg<65>o<EFBFBD><6F> jest zbyt ma<6D>a
|
||
{ // AccPreferred=-0.9; //hamowanie maksymalne, bo jest za blisko
|
||
if (k < 10.0) // k - pr<70>dko<6B><6F> tego z przodu
|
||
{ // je<6A>li tamten porusza si<73> z niewielk<6C> pr<70>dko<6B>ci<63> albo stoi
|
||
if (OrderCurrentGet() & Connect)
|
||
{ // je<6A>li spinanie, to jecha<68> dalej
|
||
AccPreferred = 0.2; // nie hamuj
|
||
VelNext = VelDesired = 2.0; // i pakuj si<73> na tamtego
|
||
}
|
||
else // a normalnie to hamowa<77>
|
||
{
|
||
AccPreferred = -1.0; // to hamuj maksymalnie
|
||
VelNext = VelDesired = 0.0; // i nie pakuj si<73> na
|
||
// tamtego
|
||
}
|
||
}
|
||
else // je<6A>li oba jad<61>, to przyhamuj lekko i ogranicz pr<70>dko<6B><6F>
|
||
{
|
||
if (k < vel) // jak tamten jedzie wolniej
|
||
if (d < fBrakeDist) // a jest w drodze hamowania
|
||
{
|
||
if (AccPreferred > fAccThreshold)
|
||
AccPreferred =
|
||
fAccThreshold; // to przyhamuj troszk<7A>
|
||
VelNext = VelDesired = int(k); // to chyba ju<6A> sobie
|
||
// dohamuje wed<65>ug
|
||
// uznania
|
||
}
|
||
}
|
||
ReactionTime = 0.1; // orientuj si<73>, bo jest goraco
|
||
}
|
||
else
|
||
{ // je<6A>li odleg<65>o<EFBFBD><6F> jest wi<77>ksza, ustali<6C> maksymalne mo<6D>liwe
|
||
// przyspieszenie (hamowanie)
|
||
k = (k * k - vel * vel) / (25.92 * d); // energia kinetyczna
|
||
// dzielona przez mas<61> i
|
||
// drog<6F> daje
|
||
// przyspieszenie
|
||
if (k > 0.0)
|
||
k *= 1.5; // jed<65> szybciej, je<6A>li mo<6D>esz
|
||
// double ak=(c->Connected->V>0?1.0:-1.0)*c->Connected->AccS;
|
||
// //przyspieszenie tamtego
|
||
if (d < fBrakeDist) // a jest w drodze hamowania
|
||
if (k < AccPreferred)
|
||
{ // je<6A>li nie ma innych powod<6F>w do wolniejszej jazdy
|
||
AccPreferred = k;
|
||
if (VelNext > c->Connected->Vel)
|
||
{
|
||
VelNext =
|
||
c->Connected
|
||
->Vel; // ograniczenie do pr<70>dko<6B>ci tamtego
|
||
ActualProximityDist =
|
||
d; // i odleg<65>o<EFBFBD><6F> od tamtego jest istotniejsza
|
||
}
|
||
ReactionTime = 0.2; // zwi<77>ksz czujno<6E><6F>
|
||
}
|
||
#if LOGVELOCITY
|
||
WriteLog("Collision: AccPreferred=" + AnsiString(k));
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// sprawdzamy mo<6D>liwe ograniczenia pr<70>dko<6B>ci
|
||
if (OrderCurrentGet() & (Shunt | Obey_train)) // w Connect nie, bo moveStopHere
|
||
// odnosi si<73> do stanu po po<70><6F>czeniu
|
||
if (iDrivigFlags & moveStopHere) // je<6A>li ma czeka<6B> na woln<6C> drog<6F>
|
||
if (vel == 0.0) // a stoi
|
||
if (VelNext == 0.0) // a wyjazdu nie ma
|
||
VelDesired = 0.0; // to ma sta<74>
|
||
if (fStopTime < 0) // czas postoju przed dalsz<73> jazd<7A> (np. na przystanku)
|
||
VelDesired = 0.0; // jak ma czeka<6B>, to nie ma jazdy
|
||
// else if (VelSignal<0)
|
||
// VelDesired=fVelMax; //ile fabryka dala (Ra: uwzgl<67>dione wagony)
|
||
else if (VelSignal >= 0) // je<6A>li sk<73>ad by<62> zatrzymany na pocz<63>tku i teraz ju<6A> mo<6D>e jecha<68>
|
||
VelDesired = Global::Min0RSpeed(VelDesired, VelSignal);
|
||
|
||
if (mvOccupied->RunningTrack.Velmax >=
|
||
0) // ograniczenie pr<70>dko<6B>ci z trajektorii ruchu
|
||
VelDesired =
|
||
Global::Min0RSpeed(VelDesired,
|
||
mvOccupied->RunningTrack.Velmax); // uwaga na ograniczenia szlakowej!
|
||
if (VelforDriver >= 0) // tu jest zero przy zmianie kierunku jazdy
|
||
VelDesired = Global::Min0RSpeed(VelDesired, VelforDriver); // Ra: tu mo<6D>e by<62> 40, je<6A>li
|
||
// mechanik nie ma znajomo<6D>ci
|
||
// szlaaku, albo kierowca je<6A>dzi
|
||
// 70
|
||
if (TrainParams)
|
||
if (TrainParams->CheckTrainLatency() < 5.0)
|
||
if (TrainParams->TTVmax > 0.0)
|
||
VelDesired = Global::Min0RSpeed(
|
||
VelDesired,
|
||
TrainParams
|
||
->TTVmax); // jesli nie spozniony to nie przekracza<7A> rozkladowej
|
||
if (VelDesired > 0.0)
|
||
if ((sSemNext && sSemNext->fVelNext != 0.0) || (iDrivigFlags & moveStopHere)==0)
|
||
{ // je<6A>li mo<6D>na jecha<68>, to odpali<6C> d<>wi<77>k kierownika oraz zamkn<6B><6E> drzwi w
|
||
// sk<73>adzie, je<6A>li nie mamy czeka<6B> na sygna<6E> te<74> trzeba odpali<6C>
|
||
|
||
if (iDrivigFlags & moveGuardSignal)
|
||
{ // komunikat od kierownika tu, bo musi by<62> wolna droga i odczekany czas
|
||
// stania
|
||
iDrivigFlags &= ~moveGuardSignal; // tylko raz nada<64>
|
||
tsGuardSignal->Stop();
|
||
// w zasadzie to powinien mie<69> flag<61>, czy jest d<>wi<77>kiem radiowym, czy
|
||
// bezpo<70>rednim
|
||
// albo trzeba zrobi<62> dwa d<>wi<77>ki, jeden bezpo<70>redni, s<>yszalny w
|
||
// pobli<6C>u, a drugi radiowy, s<>yszalny w innych lokomotywach
|
||
// na razie zak<61>adam, <20>e to nie jest d<>wi<77>k radiowy, bo trzeba by zrobi<62>
|
||
// obs<62>ug<75> kana<6E><61>w radiowych itd.
|
||
if (!iGuardRadio) // je<6A>li nie przez radio
|
||
tsGuardSignal->Play(
|
||
1.0, 0, !FreeFlyModeFlag,
|
||
pVehicle->GetPosition()); // dla true jest g<>o<EFBFBD>niej
|
||
else
|
||
// if (iGuardRadio==iRadioChannel) //zgodno<6E><6F> kana<6E>u
|
||
// if (!FreeFlyModeFlag) //obserwator musi by<62> w <20>rodku pojazdu
|
||
// (albo mo<6D>e mie<69> radio przeno<6E>ne) - kierownik m<>g<EFBFBD>by powtarza<7A>
|
||
// przy braku reakcji
|
||
if (SquareMagnitude(pVehicle->GetPosition() -
|
||
Global::pCameraPosition) <
|
||
2000 * 2000) // w odleg<65>o<EFBFBD>ci mniejszej ni<6E> 2km
|
||
tsGuardSignal->Play(
|
||
1.0, 0, true,
|
||
pVehicle->GetPosition()); // d<>wi<77>k niby przez radio
|
||
}
|
||
if (iDrivigFlags & moveDoorOpened) // je<6A>li drzwi otwarte
|
||
if (!mvOccupied
|
||
->DoorOpenCtrl) // je<6A>li drzwi niesterowane przez maszynist<73>
|
||
Doors(false); // a EZT zamknie dopiero po odegraniu komunikatu
|
||
// kierownika
|
||
}
|
||
if (mvOccupied->V == 0.0)
|
||
AbsAccS = fAccGravity; // Ra 2014-03: jesli sk<73>ad stoi, to dzia<69>a na niego
|
||
// sk<73>adowa styczna grawitacji
|
||
else
|
||
AbsAccS = iDirection * mvOccupied->AccS; // przyspieszenie chwilowe, liczone
|
||
// jako r<><72>nica skierowanej pr<70>dko<6B>ci w
|
||
// czasie
|
||
// if (mvOccupied->V<0.0) AbsAccS=-AbsAccS; //Ra 2014-03: to trzeba przemy<6D>le<6C>
|
||
// if (vel<0) //je<6A>eli si<73> stacza w ty<74>; 2014-03: to jest bez sensu, bo vel>=0
|
||
// AbsAccS=-AbsAccS; //to przyspieszenie te<74> dzia<69>a wtedy w nieodpowiedni<6E> stron<6F>
|
||
// AbsAccS+=fAccGravity; //wypadkowe przyspieszenie (czy to ma sens?)
|
||
#if LOGVELOCITY
|
||
// WriteLog("VelDesired="+AnsiString(VelDesired)+",
|
||
// VelSignal="+AnsiString(VelSignal));
|
||
WriteLog("Vel=" + AnsiString(vel) + ", AbsAccS=" + AnsiString(AbsAccS) +
|
||
", AccGrav=" + AnsiString(fAccGravity));
|
||
#endif
|
||
// ustalanie zadanego przyspieszenia
|
||
//(ActualProximityDist) - odleg<65>o<EFBFBD><6F> do miejsca zmniejszenia pr<70>dko<6B>ci
|
||
//(AccPreferred) - wynika z psychyki oraz uwzgl<67>nia ju<6A> ewentualne zderzenie z
|
||
// pojazdem z przodu, ujemne gdy nale<6C>y hamowa<77>
|
||
//(AccDesired) - uwzgl<67>dnia sygna<6E>y na drodze ruchu, ujemne gdy nale<6C>y hamowa<77>
|
||
//(fAccGravity) - chwilowe przspieszenie grawitacyjne, ujemne dzia<69>a przeciwnie do
|
||
// zadanego kierunku jazdy
|
||
//(AbsAccS) - chwilowe przyspieszenie pojazu (uwzgl<67>dnia grawitacj<63>), ujemne dzia<69>a
|
||
// przeciwnie do zadanego kierunku jazdy
|
||
//(AccDesired) por<6F>wnujemy z (fAccGravity) albo (AbsAccS)
|
||
// if ((VelNext>=0.0)&&(ActualProximityDist>=0)&&(mvOccupied->Vel>=VelNext)) //gdy
|
||
// zbliza sie i jest za szybko do NOWEGO
|
||
if ((VelNext >= 0.0) && (ActualProximityDist <= scanmax) && (vel >= VelNext))
|
||
{ // gdy zbli<6C>a si<73> i jest za szybki do nowej pr<70>dko<6B>ci, albo stoi na zatrzymaniu
|
||
if (vel > 0.0)
|
||
{ // je<6A>li jedzie
|
||
if ((vel < VelNext) ?
|
||
(ActualProximityDist > fMaxProximityDist * (1 + 0.1 * vel)) :
|
||
false) // dojedz do semafora/przeszkody
|
||
{ // je<6A>li jedzie wolniej ni<6E> mo<6D>na i jest wystarczaj<61>co daleko, to mo<6D>na
|
||
// przyspieszy<7A>
|
||
if (AccPreferred > 0.0) // je<6A>li nie ma zawalidrogi
|
||
AccDesired = AccPreferred;
|
||
// VelDesired:=Min0R(VelDesired,VelReduced+VelNext);
|
||
}
|
||
else if (ActualProximityDist > fMinProximityDist)
|
||
{ // jedzie szybciej, ni<6E> trzeba na ko<6B>cu ActualProximityDist, ale jeszcze
|
||
// jest daleko
|
||
if (vel <
|
||
VelNext + 40.0) // dwustopniowe hamowanie - niski przy ma<6D>ej r<><72>nicy
|
||
{ // je<6A>li jedzie wolniej ni<6E> VelNext+35km/h //Ra: 40, <20>eby nie
|
||
// kombinowa<77> na zwrotnicach
|
||
if (VelNext == 0.0)
|
||
{ // je<6A>li ma si<73> zatrzyma<6D>, musi by<62> to robione precyzyjnie i
|
||
// skutecznie
|
||
if (ActualProximityDist <
|
||
fMaxProximityDist) // jak min<69><6E> ju<6A> maksymalny dystans
|
||
{ // po prostu hamuj (niski stopie<69>) //ma stan<61><6E>, a jest w
|
||
// drodze hamowania albo ma jecha<68>
|
||
AccDesired = fAccThreshold; // hamowanie tak, aby stan<61><6E>
|
||
VelDesired = 0.0; // Min0R(VelDesired,VelNext);
|
||
}
|
||
else if (ActualProximityDist > fBrakeDist)
|
||
{ // je<6A>li ma stan<61><6E>, a mie<69>ci si<73> w drodze hamowania
|
||
if (vel < 10.0) // je<6A>li pr<70>dko<6B><6F> jest <20>atwa do zatrzymania
|
||
{ // tu jest troch<63> problem, bo do punktu zatrzymania dobija
|
||
// na raty
|
||
// AccDesired=AccDesired<0.0?0.0:0.1*AccPreferred;
|
||
AccDesired = AccPreferred; // proteza troch<63>; jak tu
|
||
// wychodzi 0.05, to loki
|
||
// maj<61> problem utrzyma<6D>
|
||
// takie przyspieszenie
|
||
}
|
||
else if (vel <= 30.0) // trzymaj 30 km/h
|
||
AccDesired = Min0R(0.5 * AccDesired,
|
||
AccPreferred); // jak jest tu 0.5, to
|
||
// samochody si<73>
|
||
// dobijaj<61> do siebie
|
||
else
|
||
AccDesired = 0.0;
|
||
}
|
||
else // 25.92 (=3.6*3.6*2) - przelicznik z km/h na m/s
|
||
if (vel <
|
||
VelNext + fVelPlus) // je<6A>li niewielkie przekroczenie
|
||
// AccDesired=0.0;
|
||
AccDesired = Min0R(0.0, AccPreferred); // proteza troch<63>: to
|
||
// niech nie hamuje,
|
||
// chyba <20>e co<63> z
|
||
// przodu
|
||
else
|
||
AccDesired = -(vel * vel) /
|
||
(25.92 * (ActualProximityDist +
|
||
0.1)); //-fMinProximityDist));//-0.1;
|
||
////mniejsze op<6F><70>nienie przy
|
||
// ma<6D>ej r<><72>nicy
|
||
ReactionTime = 0.1; // i orientuj si<73> szybciej, jak masz stan<61><6E>
|
||
}
|
||
else if (vel < VelNext + fVelPlus) // je<6A>li niewielkie
|
||
// przekroczenie, ale ma jecha<68>
|
||
AccDesired =
|
||
Min0R(0.0, AccPreferred); // to olej (zacznij luzowa<77>)
|
||
else
|
||
{ // je<6A>li wi<77>ksze przekroczenie ni<6E> fVelPlus [km/h], ale ma jecha<68>
|
||
// Ra 2F1I: jak by<62>o (VelNext+fVelPlus) tu, to hamowa<77> zbyt
|
||
// p<><70>no przed 40, a potem zbyt mocno i zwalnia<69> do 30
|
||
AccDesired = (VelNext * VelNext - vel * vel) /
|
||
(25.92 * ActualProximityDist +
|
||
0.1); // mniejsze op<6F><70>nienie przy ma<6D>ej r<><72>nicy
|
||
if (ActualProximityDist < fMaxProximityDist)
|
||
ReactionTime = 0.1; // i orientuj si<73> szybciej, je<6A>li w
|
||
// krytycznym przedziale
|
||
}
|
||
}
|
||
else // przy du<64>ej r<><72>nicy wysoki stopie<69> (1,25 potrzebnego opoznienia)
|
||
AccDesired = (VelNext * VelNext - vel * vel) /
|
||
(20.73 * ActualProximityDist +
|
||
0.1); // najpierw hamuje mocniej, potem zluzuje
|
||
if (AccPreferred < AccDesired)
|
||
AccDesired = AccPreferred; //(1+abs(AccDesired))
|
||
// ReactionTime=0.5*mvOccupied->BrakeDelay[2+2*mvOccupied->BrakeDelayFlag];
|
||
// //aby szybkosc hamowania zalezala od przyspieszenia i opoznienia
|
||
// hamulcow
|
||
// fBrakeTime=0.5*mvOccupied->BrakeDelay[2+2*mvOccupied->BrakeDelayFlag];
|
||
// //aby szybkosc hamowania zalezala od przyspieszenia i opoznienia
|
||
// hamulcow
|
||
}
|
||
else
|
||
{ // jest bli<6C>ej ni<6E> fMinProximityDist
|
||
VelDesired =
|
||
Min0R(VelDesired, VelNext); // utrzymuj predkosc bo juz blisko
|
||
if (vel <
|
||
VelNext + fVelPlus) // je<6A>li niewielkie przekroczenie, ale ma jecha<68>
|
||
AccDesired = Min0R(0.0, AccPreferred); // to olej (zacznij luzowa<77>)
|
||
ReactionTime = 0.1; // i orientuj si<73> szybciej
|
||
}
|
||
}
|
||
else // zatrzymany (vel==0.0)
|
||
// if (iDrivigFlags&moveStopHere) //to nie dotyczy podczepiania
|
||
// if ((VelNext>0.0)||(ActualProximityDist>fMaxProximityDist*1.2))
|
||
if (VelNext > 0.0)
|
||
AccDesired = AccPreferred; // mo<6D>na jecha<68>
|
||
else // je<6A>li daleko jecha<68> nie mo<6D>na
|
||
if (ActualProximityDist >
|
||
fMaxProximityDist) // ale ma kawa<77>ek do sygnalizatora
|
||
{ // if ((iDrivigFlags&moveStopHere)?false:AccPreferred>0)
|
||
if (AccPreferred > 0)
|
||
AccDesired = AccPreferred; // dociagnij do semafora;
|
||
else
|
||
VelDesired = 0.0; //,AccDesired=-fabs(fAccGravity); //stoj (hamuj z si<73><69>
|
||
// r<>wn<77> sk<73>adowej stycznej grawitacji)
|
||
}
|
||
else
|
||
VelDesired = 0.0; // VelNext=0 i stoi bli<6C>ej ni<6E> fMaxProximityDist
|
||
}
|
||
else // gdy jedzie wolniej ni<6E> potrzeba, albo nie ma przeszk<7A>d na drodze
|
||
AccDesired = (VelDesired != 0.0 ? AccPreferred : -0.01); // normalna jazda
|
||
// koniec predkosci nastepnej
|
||
if ((VelDesired >= 0.0) &&
|
||
(vel > VelDesired)) // jesli jedzie za szybko do AKTUALNEGO
|
||
if (VelDesired == 0.0) // jesli stoj, to hamuj, ale i tak juz za pozno :)
|
||
AccDesired = -0.9; // hamuj solidnie
|
||
else if ((vel < VelDesired + fVelPlus)) // o 5 km/h to olej
|
||
{
|
||
if ((AccDesired > 0.0))
|
||
AccDesired = 0.0;
|
||
}
|
||
else
|
||
AccDesired = fAccThreshold; // hamuj tak <20>rednio
|
||
// koniec predkosci aktualnej
|
||
if (fAccThreshold > -0.3) // bez sensu, ale dla towarowych korzystnie
|
||
{ // Ra 2014-03: to nie uwzgl<67>dnia odleg<65>o<EFBFBD>ci i zaczyna hamowa<77>, jak tylko zobaczy
|
||
// W4
|
||
if ((AccDesired > 0.0) &&
|
||
(VelNext >= 0.0)) // wybieg b<>d<EFBFBD> lekkie hamowanie, warunki byly zamienione
|
||
if (vel > VelNext + 100.0) // lepiej zaczac hamowac
|
||
AccDesired = fAccThreshold;
|
||
else if (vel > VelNext + 70.0)
|
||
AccDesired = 0.0; // nie spiesz si<73>, bo b<>dzie hamowanie
|
||
// koniec wybiegu i hamowania
|
||
}
|
||
if (AIControllFlag)
|
||
{ // cz<63><7A><EFBFBD> wykonawcza tylko dla AI, dla cz<63>owieka jedynie napisy
|
||
if (mvControlling->ConvOvldFlag ||
|
||
!mvControlling->Mains) // WS mo<6D>e wywali<6C> z powodu b<><62>du w drutach
|
||
{ // wywali<6C> bezpiecznik nadmiarowy przetwornicy
|
||
// while (DecSpeed()); //zerowanie nap<61>du
|
||
// Controlling->ConvOvldFlag=false; //reset nadmiarowego
|
||
PrepareEngine(); // pr<70>ba ponownego za<7A><61>czenia
|
||
}
|
||
// w<><77>czanie bezpiecznika
|
||
if ((mvControlling->EngineType == ElectricSeriesMotor) ||
|
||
(mvControlling->TrainType & dt_EZT) ||
|
||
(mvControlling->EngineType == DieselElectric))
|
||
if (mvControlling->FuseFlag || Need_TryAgain)
|
||
{
|
||
Need_TryAgain =
|
||
false; // true, je<6A>li druga pozycja w elektryku nie za<7A>apa<70>a
|
||
// if (!Controlling->DecScndCtrl(1)) //kr<6B>cenie po ma<6D>u
|
||
// if (!Controlling->DecMainCtrl(1)) //nastawnik jazdy na 0
|
||
mvControlling->DecScndCtrl(2); // nastawnik bocznikowania na 0
|
||
mvControlling->DecMainCtrl(2); // nastawnik jazdy na 0
|
||
mvControlling->MainSwitch(
|
||
true); // Ra: doda<64>em, bo EN57 stawa<77>y po wywaleniu
|
||
if (!mvControlling->FuseOn())
|
||
HelpMeFlag = true;
|
||
else
|
||
{
|
||
++iDriverFailCount;
|
||
if (iDriverFailCount > maxdriverfails)
|
||
Psyche = Easyman;
|
||
if (iDriverFailCount > maxdriverfails * 2)
|
||
SetDriverPsyche();
|
||
}
|
||
}
|
||
if (mvOccupied->BrakeSystem == Pneumatic) // nape<70>nianie uderzeniowe
|
||
if (mvOccupied->BrakeHandle == FV4a)
|
||
{
|
||
if (mvOccupied->BrakeCtrlPos == -2)
|
||
mvOccupied->BrakeLevelSet(0);
|
||
// if
|
||
// ((mvOccupied->BrakeCtrlPos<0)&&(mvOccupied->PipeBrakePress<0.01))//{(CntrlPipePress-(Volume/BrakeVVolume/10)<0.01)})
|
||
// mvOccupied->IncBrakeLevel();
|
||
if ((mvOccupied->PipePress < 3.0) && (AccDesired > -0.03))
|
||
mvOccupied->BrakeReleaser(1);
|
||
if ((mvOccupied->BrakeCtrlPos == 0) && (AbsAccS < 0.0) &&
|
||
(AccDesired > -0.03))
|
||
// if FuzzyLogicAI(CntrlPipePress-PipePress,0.01,1))
|
||
// if
|
||
// ((mvOccupied->BrakePress>0.5)&&(mvOccupied->LocalBrakePos<0.5))//{((Volume/BrakeVVolume/10)<0.485)})
|
||
if ((mvOccupied->EqvtPipePress < 4.95) &&
|
||
(fReady > 0.35)) //{((Volume/BrakeVVolume/10)<0.485)})
|
||
{
|
||
if (iDrivigFlags &
|
||
moveOerlikons) // a reszta sk<73>adu jest na to gotowa
|
||
mvOccupied->BrakeLevelSet(-1); // nape<70>nianie w Oerlikonie
|
||
}
|
||
else if (Need_BrakeRelease)
|
||
{
|
||
Need_BrakeRelease = false;
|
||
mvOccupied->BrakeReleaser(1);
|
||
// DecBrakeLevel(); //z tym by jeszcze mia<69>o jaki<6B> sens
|
||
}
|
||
// if
|
||
// ((mvOccupied->BrakeCtrlPos<0)&&(mvOccupied->BrakePress<0.3))//{(CntrlPipePress-(Volume/BrakeVVolume/10)<0.01)})
|
||
if ((mvOccupied->BrakeCtrlPos < 0) &&
|
||
(mvOccupied->EqvtPipePress >
|
||
(fReady < 0.25 ?
|
||
5.1 :
|
||
5.2))) //{(CntrlPipePress-(Volume/BrakeVVolume/10)<0.01)})
|
||
mvOccupied->IncBrakeLevel();
|
||
}
|
||
#if LOGVELOCITY
|
||
WriteLog("Dist=" + FloatToStrF(ActualProximityDist, ffFixed, 7, 1) +
|
||
", VelDesired=" + FloatToStrF(VelDesired, ffFixed, 7, 1) +
|
||
", AccDesired=" + FloatToStrF(AccDesired, ffFixed, 7, 3) +
|
||
", VelSignal=" + AnsiString(VelSignal) + ", VelNext=" +
|
||
AnsiString(VelNext));
|
||
#endif
|
||
if (AccDesired > 0.1)
|
||
if (vel < 10.0) // Ra 2F1H: je<6A>li pr<70>dko<6B><6F> jest ma<6D>a, a mo<6D>na przyspiesza<7A>,
|
||
// to nie ogranicza<7A> przyspieszenia do 0.5m/ss
|
||
AccDesired = 0.9; // przy ma<6D>ych pr<70>dko<6B>ciach mo<6D>e by<62> trudno utrzyma<6D>
|
||
// ma<6D>e przyspieszenie
|
||
// Ra 2F1I: wy<77><79>czy<7A> kiedy<64> to u<>rednianie i przeanalizowa<77> skanowanie, czemu
|
||
// migocze
|
||
if (AccDesired > -0.15) // hamowania lepeiej nie u<>rednia<69>
|
||
AccDesired = fAccDesiredAv =
|
||
0.2 * AccDesired +
|
||
0.8 * fAccDesiredAv; // u<>rednione, <20>eby ograniczy<7A> migotanie
|
||
if (VelDesired == 0.0)
|
||
if (AccDesired >= -0.01)
|
||
AccDesired = -0.01; // Ra 2F1J: jeszcze jedna prowizoryczna <20>atka
|
||
if (AccDesired >= 0.0)
|
||
if (iDrivigFlags & movePress)
|
||
mvOccupied->BrakeReleaser(1); // wyluzuj lokomotyw<79> - mo<6D>e by<62> wi<77>cej!
|
||
else if (OrderList[OrderPos] !=
|
||
Disconnect) // przy od<6F><64>czaniu nie zwalniamy tu hamulca
|
||
if ((AccDesired > 0.0) ||
|
||
(fAccGravity * fAccGravity <
|
||
0.001)) // luzuj tylko na plaskim lub przy ruszaniu
|
||
{
|
||
while (DecBrake())
|
||
; // je<6A>li przyspieszamy, to nie hamujemy
|
||
if (mvOccupied->BrakePress > 0.4)
|
||
mvOccupied->BrakeReleaser(
|
||
1); // wyluzuj lokomotyw<79>, to szybciej ruszymy
|
||
}
|
||
// margines dla pr<70>dko<6B>ci jest doliczany tylko je<6A>li oczekiwana pr<70>dko<6B><6F> jest
|
||
// wi<77>ksza od 5km/h
|
||
if (!(iDrivigFlags & movePress))
|
||
{ // je<6A>li nie dociskanie
|
||
if (AccDesired < -0.1)
|
||
while (DecSpeed())
|
||
; // je<6A>li hamujemy, to nie przyspieszamy
|
||
else if (((fAccGravity < -0.01) ? AccDesired < 0.0 :
|
||
AbsAccS > AccDesired) ||
|
||
(vel > VelDesired)) // jak za bardzo przyspiesza albo pr<70>dko<6B><6F>
|
||
// przekroczona
|
||
DecSpeed(); // pojedyncze cofni<6E>cie pozycji, bo na zero to przesada
|
||
}
|
||
// yB: usuni<6E>te r<><72>ne dziwne warunki, oddzielamy cz<63><7A><EFBFBD> zadaj<61>c<EFBFBD> od wykonawczej
|
||
// zwiekszanie predkosci
|
||
// Ra 2F1H: jest konflikt histerezy pomi<6D>dzy nastawion<6F> pozycj<63> a uzyskiwanym
|
||
// przyspieszeniem - utrzymanie pozycji powoduje przekroczenie przyspieszenia
|
||
if (AbsAccS <
|
||
AccDesired) // je<6A>li przyspieszenie pojazdu jest mniejsze ni<6E> <20><>dane oraz
|
||
if (vel < VelDesired - fVelMinus) // je<6A>li pr<70>dko<6B><6F> w kierunku czo<7A>a jest
|
||
// mniejsza od dozwolonej o margines
|
||
if ((ActualProximityDist > fMaxProximityDist) ? true : (vel < VelNext))
|
||
IncSpeed(); // to mo<6D>na przyspieszy<7A>
|
||
// if ((AbsAccS<AccDesired)&&(vel<VelDesired))
|
||
// if (!MaxVelFlag) //Ra: to nie jest u<>ywane
|
||
// if (!IncSpeed()) //Ra: to tutaj jest bez sensu, bo nie doci<63>gnie do
|
||
// bezoporowej
|
||
// MaxVelFlag=true; //Ra: to nie jest u<>ywane
|
||
// else
|
||
// MaxVelFlag=false; //Ra: to nie jest u<>ywane
|
||
// if (Vel<VelDesired*0.85) and (AccDesired>0) and
|
||
// (EngineType=ElectricSeriesMotor)
|
||
// and (RList[MainCtrlPos].R>0.0) and (not DelayCtrlFlag))
|
||
// if (Im<Imin) and Ready=True {(BrakePress<0.01*MaxBrakePress)})
|
||
// IncMainCtrl(1); //zwieksz nastawnik skoro mo<6D>esz - tak aby si<73> ustawic na
|
||
// bezoporowej
|
||
|
||
// yB: usuni<6E>te r<><72>ne dziwne warunki, oddzielamy cz<63><7A><EFBFBD> zadaj<61>c<EFBFBD> od wykonawczej
|
||
// zmniejszanie predkosci
|
||
if (mvOccupied->TrainType &
|
||
dt_EZT) // w<>a<EFBFBD>ciwie, to warunek powinien by<62> na dzia<69>aj<61>cy EP
|
||
{ // Ra: to dobrze hamuje EP w EZT
|
||
if ((AccDesired <= fAccThreshold) ? // je<6A>li hamowa<77> - u g<>ry ustawia si<73>
|
||
// hamowanie na fAccThreshold
|
||
((AbsAccS > AccDesired) || (mvOccupied->BrakeCtrlPos < 0)) :
|
||
false) // hamowa<77> bardziej, gdy aktualne op<6F><70>nienie hamowania
|
||
// mniejsze ni<6E> (AccDesired)
|
||
IncBrake();
|
||
else if (OrderList[OrderPos] !=
|
||
Disconnect) // przy od<6F><64>czaniu nie zwalniamy tu hamulca
|
||
if (AbsAccS <
|
||
AccDesired -
|
||
0.05) // je<6A>li op<6F><70>nienie wi<77>ksze od wymaganego (z histerez<65>)
|
||
{ // luzowanie, gdy za du<64>o
|
||
if (mvOccupied->BrakeCtrlPos >= 0)
|
||
DecBrake(); // tutaj zmniejsza<7A>o o 1 przy odczepianiu
|
||
}
|
||
else if (mvOccupied->Handle->TimeEP)
|
||
{
|
||
if (mvOccupied->Handle->GetPos(bh_EPR) -
|
||
mvOccupied->Handle->GetPos(bh_EPN) <
|
||
0.1)
|
||
mvOccupied->SwitchEPBrake(0);
|
||
else
|
||
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EPN));
|
||
}
|
||
// else if (mvOccupied->BrakeCtrlPos<0) IncBrake(); //ustawienie
|
||
// jazdy (pozycja 0)
|
||
// else if (mvOccupied->BrakeCtrlPos>0) DecBrake();
|
||
}
|
||
else
|
||
{ // a stara wersja w miar<61> dobrze dzia<69>a na sk<73>ady wagonowe
|
||
// if (mvOccupied->Handle->Time)
|
||
// mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_MB));
|
||
// //najwyzej sobie przestawi
|
||
if (((fAccGravity < -0.05) && (vel < 0)) ||
|
||
((AccDesired < fAccGravity - 0.1) &&
|
||
(AbsAccS >
|
||
AccDesired + 0.05))) // u g<>ry ustawia si<73> hamowanie na fAccThreshold
|
||
// if not MinVelFlag)
|
||
if (fBrakeTime < 0 ? true : (AccDesired < fAccGravity - 0.3) ||
|
||
(mvOccupied->BrakeCtrlPos <= 0))
|
||
if (!IncBrake()) // je<6A>li up<75>yn<79><6E> czas reakcji hamulca, chyba <20>e
|
||
// nag<61>e albo luzowa<77>
|
||
MinVelFlag = true;
|
||
else
|
||
{
|
||
MinVelFlag = false;
|
||
fBrakeTime =
|
||
3 +
|
||
0.5 *
|
||
(mvOccupied
|
||
->BrakeDelay[2 + 2 * mvOccupied->BrakeDelayFlag] -
|
||
3);
|
||
// Ra: ten czas nale<6C>y zmniejszy<7A>, je<6A>li czas dojazdu do
|
||
// zatrzymania jest mniejszy
|
||
fBrakeTime *= 0.5; // Ra: tymczasowo, bo prze<7A>yna S1
|
||
}
|
||
if ((AccDesired < fAccGravity - 0.05) && (AbsAccS < AccDesired - 0.2))
|
||
// if ((AccDesired<0.0)&&(AbsAccS<AccDesired-0.1)) //ST44 nie hamuje na
|
||
// czas, 2-4km/h po mini<6E>ciu tarczy
|
||
// if (fBrakeTime<0)
|
||
{ // jak hamuje, to nie tykaj kranu za cz<63>sto
|
||
// yB: luzuje hamulec dopiero przy r<><72>nicy op<6F><70>nie<69> rz<72>du 0.2
|
||
if (OrderList[OrderPos] !=
|
||
Disconnect) // przy od<6F><64>czaniu nie zwalniamy tu hamulca
|
||
DecBrake(); // tutaj zmniejsza<7A>o o 1 przy odczepianiu
|
||
fBrakeTime =
|
||
(mvOccupied->BrakeDelay[1 + 2 * mvOccupied->BrakeDelayFlag]) / 3.0;
|
||
fBrakeTime *= 0.5; // Ra: tymczasowo, bo prze<7A>yna S1
|
||
}
|
||
}
|
||
// Mietek-end1
|
||
SpeedSet(); // ci<63>gla regulacja pr<70>dko<6B>ci
|
||
#if LOGVELOCITY
|
||
WriteLog("BrakePos=" + AnsiString(mvOccupied->BrakeCtrlPos) + ", MainCtrl=" +
|
||
AnsiString(mvControlling->MainCtrlPos));
|
||
#endif
|
||
|
||
/* //Ra: mamy teraz wska<6B>nik na cz<63>on silnikowy, gorzej jak s<> dwa w
|
||
ukrotnieniu...
|
||
//zapobieganie poslizgowi w czlonie silnikowym; Ra: Couplers[1] powinno
|
||
by<62>
|
||
if (Controlling->Couplers[0].Connected!=NULL)
|
||
if (TestFlag(Controlling->Couplers[0].CouplingFlag,ctrain_controll))
|
||
if (Controlling->Couplers[0].Connected->SlippingWheels)
|
||
if (Controlling->ScndCtrlPos>0?!Controlling->DecScndCtrl(1):true)
|
||
{
|
||
if (!Controlling->DecMainCtrl(1))
|
||
if (mvOccupied->BrakeCtrlPos==mvOccupied->BrakeCtrlPosNo)
|
||
mvOccupied->DecBrakeLevel();
|
||
++iDriverFailCount;
|
||
}
|
||
*/
|
||
// zapobieganie poslizgowi u nas
|
||
if (mvControlling->SlippingWheels)
|
||
{
|
||
if (!mvControlling->DecScndCtrl(2)) // bocznik na zero
|
||
mvControlling->DecMainCtrl(1);
|
||
if (mvOccupied->BrakeCtrlPos ==
|
||
mvOccupied->BrakeCtrlPosNo) // je<6A>li ostatnia pozycja hamowania
|
||
mvOccupied->DecBrakeLevel(); // to cofnij hamulec
|
||
else
|
||
mvControlling->AntiSlippingButton();
|
||
++iDriverFailCount;
|
||
mvControlling->SlippingWheels = false; // flaga ju<6A> wykorzystana
|
||
}
|
||
if (iDriverFailCount > maxdriverfails)
|
||
{
|
||
Psyche = Easyman;
|
||
if (iDriverFailCount > maxdriverfails * 2)
|
||
SetDriverPsyche();
|
||
}
|
||
} // if (AIControllFlag)
|
||
else
|
||
{ // tu mozna da<64> komunikaty tekstowe albo s<>owne: przyspiesz, hamuj (lekko,
|
||
// <20>rednio, mocno)
|
||
}
|
||
} // kierunek r<><72>ny od zera
|
||
else
|
||
{ // tutaj, gdy pojazd jest wy<77><79>czony
|
||
if (!AIControllFlag) // je<6A>li sterowanie jest w gestii u<>ytkownika
|
||
if (mvOccupied->Battery) // czy u<>ytkownik za<7A><61>czy<7A> bateri<72>?
|
||
if (mvOccupied->ActiveDir) // czy ustawi<77> kierunek
|
||
{ // je<6A>li tak, to uruchomienie skanowania
|
||
CheckVehicles(); // sprawdzi<7A> sk<73>ad
|
||
TableClear(); // resetowanie tabelki skanowania
|
||
PrepareEngine(); // uruchomienie
|
||
}
|
||
}
|
||
if (AIControllFlag)
|
||
{ // odhamowywanie sk<73>adu po zatrzymaniu i zabezpieczanie lokomotywy
|
||
if ((OrderList[OrderPos] & (Disconnect | Connect)) ==
|
||
0) // przy (p)od<6F><64>czaniu nie zwalniamy tu hamulca
|
||
if ((mvOccupied->V == 0.0) && ((VelDesired == 0.0) || (AccDesired == 0.0)))
|
||
if ((mvOccupied->BrakeCtrlPos < 1) || !mvOccupied->DecBrakeLevel())
|
||
mvOccupied->IncLocalBrakeLevel(1); // dodatkowy na pozycj<63> 1
|
||
}
|
||
break; // rzeczy robione przy jezdzie
|
||
} // switch (OrderList[OrderPos])
|
||
// kasowanie licznika czasu
|
||
LastReactionTime = 0.0;
|
||
UpdateOK = true;
|
||
} // if ((LastReactionTime>Min0R(ReactionTime,2.0)))
|
||
else
|
||
LastReactionTime += dt;
|
||
|
||
if ((fLastStopExpDist > 0.0) && (mvOccupied->DistCounter > fLastStopExpDist))
|
||
{
|
||
iStationStart = TrainParams->StationIndex; // zaktualizowa<77> wy<77>wietlanie rozk<7A>adu
|
||
fLastStopExpDist = -1.0f; // usun<75><6E> licznik
|
||
}
|
||
|
||
if (AIControllFlag)
|
||
{
|
||
if (fWarningDuration > 0.0) // je<6A>li pozosta<74>o co<63> do wytr<74>bienia
|
||
{ // tr<74>bienie trwa nadal
|
||
fWarningDuration = fWarningDuration - dt;
|
||
if (fWarningDuration < 0.05)
|
||
mvOccupied->WarningSignal = 0; // a tu si<73> ko<6B>czy
|
||
if (ReactionTime > fWarningDuration)
|
||
ReactionTime =
|
||
fWarningDuration; // wcze<7A>niejszy przeb<65>ysk <20>wiadomo<6D>ci, by zako<6B>czy<7A> tr<74>bienie
|
||
}
|
||
if (mvOccupied->Vel >=
|
||
3.0) // jesli jedzie, mo<6D>na odblokowa<77> tr<74>bienie, bo si<73> wtedy nie w<><77>czy
|
||
{
|
||
iDrivigFlags &= ~moveStartHornDone; // zatr<74>bi dopiero jak nast<73>pnym razem stanie
|
||
iDrivigFlags |= moveStartHorn; // i tr<74>bi<62> przed nast<73>pnym ruszeniem
|
||
}
|
||
return UpdateOK;
|
||
}
|
||
else // if (AIControllFlag)
|
||
return false; // AI nie obs<62>uguje
|
||
}
|
||
|
||
void TController::JumpToNextOrder()
|
||
{ // wykonanie kolejnej komendy z tablicy rozkaz<61>w
|
||
if (OrderList[OrderPos] != Wait_for_orders)
|
||
{
|
||
if (OrderList[OrderPos] & Change_direction) // je<6A>li zmiana kierunku
|
||
if (OrderList[OrderPos] != Change_direction) // ale na<6E>o<EFBFBD>ona na co<63>
|
||
{
|
||
OrderList[OrderPos] =
|
||
TOrders(OrderList[OrderPos] &
|
||
~Change_direction); // usuni<6E>cie zmiany kierunku z innej komendy
|
||
OrderCheck();
|
||
return;
|
||
}
|
||
if (OrderPos < maxorders - 1)
|
||
++OrderPos;
|
||
else
|
||
OrderPos = 0;
|
||
}
|
||
OrderCheck();
|
||
#if LOGORDERS
|
||
WriteLog("--> JumpToNextOrder");
|
||
OrdersDump(); // normalnie nie ma po co tego wypisywa<77>
|
||
#endif
|
||
};
|
||
|
||
void TController::JumpToFirstOrder()
|
||
{ // taki relikt
|
||
OrderPos = 1;
|
||
if (OrderTop == 0)
|
||
OrderTop = 1;
|
||
OrderCheck();
|
||
#if LOGORDERS
|
||
WriteLog("--> JumpToFirstOrder");
|
||
OrdersDump(); // normalnie nie ma po co tego wypisywa<77>
|
||
#endif
|
||
};
|
||
|
||
void TController::OrderCheck()
|
||
{ // reakcja na zmian<61> rozkazu
|
||
if (OrderList[OrderPos] & (Shunt | Connect | Obey_train))
|
||
CheckVehicles(); // sprawdzi<7A> <20>wiat<61>a
|
||
if (OrderList[OrderPos] & Change_direction) // mo<6D>e by<62> na<6E>o<EFBFBD>ona na inn<6E> i wtedy ma priorytet
|
||
iDirectionOrder = -iDirection; // trzeba zmieni<6E> jawnie, bo si<73> nie domy<6D>li
|
||
else if (OrderList[OrderPos] == Obey_train)
|
||
iDrivigFlags |= moveStopPoint; // W4 s<> widziane
|
||
else if (OrderList[OrderPos] == Disconnect)
|
||
iVehicleCount = iVehicleCount < 0 ? 0 : iVehicleCount; // odczepianie lokomotywy
|
||
else if (OrderList[OrderPos] == Connect)
|
||
iDrivigFlags &= ~moveStopPoint; // podczas jazdy na po<70><6F>czenie nie zwraca<63> uwagi na W4
|
||
else if (OrderList[OrderPos] == Wait_for_orders)
|
||
OrdersClear(); // czyszczenie rozkaz<61>w i przeskok do zerowej pozycji
|
||
}
|
||
|
||
void TController::OrderNext(TOrders NewOrder)
|
||
{ // ustawienie rozkazu do wykonania jako nast<73>pny
|
||
if (OrderList[OrderPos] == NewOrder)
|
||
return; // je<6A>li robi to, co trzeba, to koniec
|
||
if (!OrderPos)
|
||
OrderPos = 1; // na pozycji zerowej pozostaje czekanie
|
||
OrderTop = OrderPos; // ale mo<6D>e jest czym<79> zaj<61>ty na razie
|
||
if (NewOrder >= Shunt) // je<6A>li ma jecha<68>
|
||
{ // ale mo<6D>e by<62> zaj<61>ty chwilowymi operacjami
|
||
while (OrderList[OrderTop] ? OrderList[OrderTop] < Shunt : false) // je<6A>li co<63> robi
|
||
++OrderTop; // pomijamy wszystkie tymczasowe prace
|
||
}
|
||
else
|
||
{ // je<6A>li ma ustawion<6F> jazd<7A>, to wy<77><79>czamy na rzecz operacji
|
||
while (OrderList[OrderTop] ?
|
||
(OrderList[OrderTop] < Shunt) && (OrderList[OrderTop] != NewOrder) :
|
||
false) // je<6A>li co<63> robi
|
||
++OrderTop; // pomijamy wszystkie tymczasowe prace
|
||
}
|
||
OrderList[OrderTop++] = NewOrder; // dodanie rozkazu jako nast<73>pnego
|
||
#if LOGORDERS
|
||
WriteLog("--> OrderNext");
|
||
OrdersDump(); // normalnie nie ma po co tego wypisywa<77>
|
||
#endif
|
||
}
|
||
|
||
void TController::OrderPush(TOrders NewOrder)
|
||
{ // zapisanie na stosie kolejnego rozkazu do wykonania
|
||
if (OrderPos == OrderTop) // je<6A>li mia<69>by by<62> zapis na aktalnej pozycji
|
||
if (OrderList[OrderPos] < Shunt) // ale nie jedzie
|
||
++OrderTop; // niekt<6B>re operacje musz<73> zosta<74> najpierw doko<6B>czone => zapis na kolejnej
|
||
if (OrderList[OrderTop] != NewOrder) // je<6A>li jest to samo, to nie dodajemy
|
||
OrderList[OrderTop++] = NewOrder; // dodanie rozkazu na stos
|
||
// if (OrderTop<OrderPos) OrderTop=OrderPos;
|
||
if (OrderTop >= maxorders)
|
||
ErrorLog("Commands overflow: The program will now crash");
|
||
#if LOGORDERS
|
||
WriteLog("--> OrderPush");
|
||
OrdersDump(); // normalnie nie ma po co tego wypisywa<77>
|
||
#endif
|
||
}
|
||
|
||
void TController::OrdersDump()
|
||
{ // wypisanie kolejnych rozkaz<61>w do logu
|
||
WriteLog("Orders for " + pVehicle->asName + ":");
|
||
for (int b = 0; b < maxorders; ++b)
|
||
{
|
||
WriteLog(to_string(b) + ": " + Order2Str(OrderList[b]) + (OrderPos == b ? " <-" : ""));
|
||
if (b) // z wyj<79>tkiem pierwszej pozycji
|
||
if (OrderList[b] == Wait_for_orders) // je<6A>li ko<6B>cowa komenda
|
||
break; // dalej nie trzeba
|
||
}
|
||
};
|
||
|
||
inline TOrders TController::OrderCurrentGet()
|
||
{
|
||
return OrderList[OrderPos];
|
||
}
|
||
|
||
inline TOrders TController::OrderNextGet()
|
||
{
|
||
return OrderList[OrderPos + 1];
|
||
}
|
||
|
||
void TController::OrdersInit(double fVel)
|
||
{ // wype<70>nianie tabelki rozkaz<61>w na podstawie rozk<7A>adu
|
||
// ustawienie kolejno<6E>ci komend, niezale<6C>nie kto prowadzi
|
||
// Mechanik->OrderPush(Wait_for_orders); //czekanie na lepsze czasy
|
||
// OrderPos=OrderTop=0; //wype<70>niamy od pozycji 0
|
||
OrdersClear(); // usuni<6E>cie poprzedniej tabeli
|
||
OrderPush(Prepare_engine); // najpierw odpalenie silnika
|
||
if (TrainParams->TrainName == "none")
|
||
{ // brak rozk<7A>adu to jazda manewrowa
|
||
if (fVel > 0.05) // typowo 0.1 oznacza gotowo<77><6F> do jazdy, 0.01 tylko za<7A><61>czenie silnika
|
||
OrderPush(Shunt); // je<6A>li nie ma rozk<7A>adu, to manewruje
|
||
}
|
||
else
|
||
{ // je<6A>li z rozk<7A>adem, to jedzie na szlak
|
||
if ((fVel > 0.0) && (fVel < 0.02))
|
||
OrderPush(Shunt); // dla pr<70>dko<6B>ci 0.01 w<><77>czamy jazd<7A> manewrow<6F>
|
||
else if (TrainParams ?
|
||
(TrainParams->DirectionChange() ? // je<6A>li obr<62>t na pierwszym przystanku
|
||
((iDrivigFlags &
|
||
movePushPull) ? // SZT r<>wnie<69>! SN61 zale<6C>nie od wagon<6F>w...
|
||
(TrainParams->TimeTable[1].StationName == TrainParams->Relation1) :
|
||
false) :
|
||
false) :
|
||
true)
|
||
OrderPush(Shunt); // a teraz start b<>dzie w manewrowym, a tryb poci<63>gowy w<><77>czy W4
|
||
else
|
||
// je<6A>li start z pierwszej stacji i jednocze<7A>nie jest na niej zmiana kierunku, to EZT ma
|
||
// mie<69> Shunt
|
||
OrderPush(Obey_train); // dla starych scenerii start w trybie pociagowym
|
||
if (DebugModeFlag) // normalnie nie ma po co tego wypisywa<77>
|
||
WriteLog("/* Timetable: " + TrainParams->ShowRelation());
|
||
TMTableLine *t;
|
||
for (int i = 0; i <= TrainParams->StationCount; ++i)
|
||
{
|
||
t = TrainParams->TimeTable + i;
|
||
if (DebugModeFlag) // normalnie nie ma po co tego wypisywa<77>
|
||
WriteLog(AnsiString(t->StationName.c_str()) + " " + AnsiString((int)t->Ah) + ":" +
|
||
AnsiString((int)t->Am) + ", " + AnsiString((int)t->Dh) + ":" +
|
||
AnsiString((int)t->Dm) + " " + AnsiString(t->StationWare.c_str()));
|
||
if (AnsiString(t->StationWare.c_str()).Pos("@"))
|
||
{ // zmiana kierunku i dalsza jazda wg rozk<7A>adu
|
||
if (iDrivigFlags & movePushPull) // SZT r<>wnie<69>! SN61 zale<6C>nie od wagon<6F>w...
|
||
{ // je<6A>li sk<73>ad zespolony, wystarczy zmieni<6E> kierunek jazdy
|
||
OrderPush(Change_direction); // zmiana kierunku
|
||
}
|
||
else
|
||
{ // dla zwyk<79>ego sk<73>adu wagonowego odczepiamy lokomotyw<79>
|
||
OrderPush(Disconnect); // odczepienie lokomotywy
|
||
OrderPush(Shunt); // a dalej manewry
|
||
if (i <= TrainParams->StationCount) // 130827: to si<73> jednak nie sprawdza
|
||
{ //"@" na ostatniej robi tylko odpi<70>cie
|
||
// OrderPush(Change_direction); //zmiana kierunku
|
||
// OrderPush(Shunt); //jazda na drug<75> stron<6F> sk<73>adu
|
||
// OrderPush(Change_direction); //zmiana kierunku
|
||
// OrderPush(Connect); //jazda pod wagony
|
||
}
|
||
}
|
||
if (i < TrainParams->StationCount) // jak nie ostatnia stacja
|
||
OrderPush(Obey_train); // to dalej wg rozk<7A>adu
|
||
}
|
||
}
|
||
if (DebugModeFlag) // normalnie nie ma po co tego wypisywa<77>
|
||
WriteLog("*/");
|
||
OrderPush(Shunt); // po wykonaniu rozk<7A>adu prze<7A><65>czy si<73> na manewry
|
||
}
|
||
// McZapkie-100302 - to ma byc wyzwalane ze scenerii
|
||
if (fVel == 0.0)
|
||
SetVelocity(0, 0, stopSleep); // je<6A>li nie ma pr<70>dko<6B>ci pocz<63>tkowej, to <20>pi
|
||
else
|
||
{ // je<6A>li podana niezerowa pr<70>dko<6B><6F>
|
||
if ((fVel >= 1.0) ||
|
||
(fVel < 0.02)) // je<6A>li ma jecha<68> - dla 0.01 ma podjecha<68> manewrowo po podaniu sygna<6E>u
|
||
iDrivigFlags = (iDrivigFlags & ~moveStopHere) |
|
||
moveStopCloser; // to do nast<73>pnego W4 ma podjecha<68> blisko
|
||
else
|
||
iDrivigFlags |= moveStopHere; // czeka<6B> na sygna<6E>
|
||
JumpToFirstOrder();
|
||
if (fVel >= 1.0) // je<6A>li ma jecha<68>
|
||
SetVelocity(fVel, -1); // ma ustawi<77> <20><>dan<61> pr<70>dko<6B><6F>
|
||
else
|
||
SetVelocity(0, 0, stopSleep); // pr<70>dko<6B><6F> w przedziale (0;1) oznacza, <20>e ma sta<74>
|
||
}
|
||
#if LOGORDERS
|
||
WriteLog("--> OrdersInit");
|
||
#endif
|
||
if (DebugModeFlag) // normalnie nie ma po co tego wypisywa<77>
|
||
OrdersDump(); // wypisanie kontrolne tabelki rozkaz<61>w
|
||
// McZapkie! - zeby w ogole AI ruszyl to musi wykonac powyzsze rozkazy
|
||
// Ale mozna by je zapodac ze scenerii
|
||
};
|
||
|
||
string TController::StopReasonText()
|
||
{ // informacja tekstowa o przyczynie zatrzymania
|
||
if (eStopReason != 7) // zawalidroga b<>dzie inaczej
|
||
return StopReasonTable[eStopReason];
|
||
else
|
||
return "Blocked by " + (pVehicles[0]->PrevAny()->GetName());
|
||
};
|
||
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
// McZapkie: skanowanie semafor<6F>w
|
||
// Ra: stare funkcje skanuj<75>ce, u<>ywane podczas manewr<77>w do szukania sygnalizatora z ty<74>u
|
||
//- nie reaguj<75> na PutValues, bo nie ma takiej potrzeby
|
||
//- rozpoznaj<61> tylko zerow<6F> pr<70>dko<6B><6F> (jako koniec toru i brak podstaw do dalszego skanowania)
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
|
||
/* //nie u<>ywane
|
||
double TController::Distance(vector3 &p1,vector3 &n,vector3 &p2)
|
||
{//Ra:obliczenie odleg<65>o<EFBFBD>ci punktu (p1) od p<>aszczyzny o wektorze normalnym (n) przechodz<64>cej przez
|
||
(p2)
|
||
return n.x*(p1.x-p2.x)+n.y*(p1.y-p2.y)+n.z*(p1.z-p2.z); //ax1+by1+cz1+d, gdzie d=-(ax2+by2+cz2)
|
||
};
|
||
*/
|
||
|
||
bool TController::BackwardTrackBusy(TTrack *Track)
|
||
{ // najpierw sprawdzamy, czy na danym torze s<> pojazdy z innego sk<73>adu
|
||
if (Track->iNumDynamics)
|
||
{ // je<6A>li tylko z w<>asnego sk<73>adu, to tor jest wolny
|
||
for (int i = 0; i < Track->iNumDynamics; ++i)
|
||
if (Track->Dynamics[i]->ctOwner != this) // je<6A>li jest jaki<6B> cudzy
|
||
return true; // to tor jest zaj<61>ty i skanowanie nie obowi<77>zuje
|
||
}
|
||
return false; // wolny
|
||
};
|
||
|
||
TEvent * TController::CheckTrackEventBackward(double fDirection, TTrack *Track)
|
||
{ // sprawdzanie eventu w torze, czy jest sygna<6E>owym - skanowanie do ty<74>u
|
||
TEvent *e = (fDirection > 0) ? Track->evEvent2 : Track->evEvent1;
|
||
if (e)
|
||
if (!e->bEnabled) // je<6A>li sygna<6E>owy (nie dodawany do kolejki)
|
||
if (e->Type == tp_GetValues) // PutValues nie mo<6D>e si<73> zmieni<6E>
|
||
return e;
|
||
return NULL;
|
||
};
|
||
|
||
TTrack * TController::BackwardTraceRoute(double &fDistance, double &fDirection,
|
||
TTrack *Track, TEvent *&Event)
|
||
{ // szukanie sygnalizatora w kierunku przeciwnym jazdy (eventu odczytu kom<6F>rki pami<6D>ci)
|
||
TTrack *pTrackChVel = Track; // tor ze zmian<61> pr<70>dko<6B>ci
|
||
TTrack *pTrackFrom; // odcinek poprzedni, do znajdywania ko<6B>ca dr<64>g
|
||
double fDistChVel = -1; // odleg<65>o<EFBFBD><6F> do toru ze zmian<61> pr<70>dko<6B>ci
|
||
double fCurrentDistance = pVehicle->RaTranslationGet(); // aktualna pozycja na torze
|
||
double s = 0;
|
||
if (fDirection > 0) // je<6A>li w kierunku Point2 toru
|
||
fCurrentDistance = Track->Length() - fCurrentDistance;
|
||
if (BackwardTrackBusy(Track))
|
||
{ // jak tor zaj<61>ty innym sk<73>adem, to nie ma po co skanowa<77>
|
||
fDistance = 0; // to na tym torze stoimy
|
||
return NULL; // stop, skanowanie nie da<64>o sensownych rezultat<61>w
|
||
}
|
||
if ((Event = CheckTrackEventBackward(fDirection, Track)) != NULL)
|
||
{ // je<6A>li jest semafor na tym torze
|
||
fDistance = 0; // to na tym torze stoimy
|
||
return Track;
|
||
}
|
||
if ((Track->VelocityGet() == 0.0) || (Track->iDamageFlag & 128))
|
||
{ // jak pr<70>dkos<6F> 0 albo uszkadza, to nie ma po co skanowa<77>
|
||
fDistance = 0; // to na tym torze stoimy
|
||
return NULL; // stop, skanowanie nie da<64>o sensownych rezultat<61>w
|
||
}
|
||
while (s < fDistance)
|
||
{
|
||
// Track->ScannedFlag=true; //do pokazywania przeskanowanych tor<6F>w
|
||
pTrackFrom = Track; // zapami<6D>tanie aktualnego odcinka
|
||
s += fCurrentDistance; // doliczenie kolejnego odcinka do przeskanowanej d<>ugo<67>ci
|
||
if (fDirection > 0)
|
||
{ // je<6A>li szukanie od Point1 w kierunku Point2
|
||
if (Track->iNextDirection)
|
||
fDirection = -fDirection;
|
||
Track = Track->CurrentNext(); // mo<6D>e by<62> NULL
|
||
}
|
||
else // if (fDirection<0)
|
||
{ // je<6A>li szukanie od Point2 w kierunku Point1
|
||
if (!Track->iPrevDirection)
|
||
fDirection = -fDirection;
|
||
Track = Track->CurrentPrev(); // mo<6D>e by<62> NULL
|
||
}
|
||
if (Track == pTrackFrom)
|
||
Track = NULL; // koniec, tak jak dla tor<6F>w
|
||
if (Track ?
|
||
(Track->VelocityGet() == 0.0) || (Track->iDamageFlag & 128) ||
|
||
BackwardTrackBusy(Track) :
|
||
true)
|
||
{ // gdy dalej toru nie ma albo zerowa pr<70>dko<6B><6F>, albo uszkadza pojazd
|
||
fDistance = s;
|
||
return NULL; // zwraca NULL, <20>e skanowanie nie da<64>o sensownych rezultat<61>w
|
||
}
|
||
fCurrentDistance = Track->Length();
|
||
if ((Event = CheckTrackEventBackward(fDirection, Track)) != NULL)
|
||
{ // znaleziony tor z eventem
|
||
fDistance = s;
|
||
return Track;
|
||
}
|
||
}
|
||
Event = NULL; // jak dojdzie tu, to nie ma semafora
|
||
if (fDistChVel < 0)
|
||
{ // zwraca ostatni sprawdzony tor
|
||
fDistance = s;
|
||
return Track;
|
||
}
|
||
fDistance = fDistChVel; // odleg<65>o<EFBFBD><6F> do zmiany pr<70>dko<6B>ci
|
||
return pTrackChVel; // i tor na kt<6B>rym si<73> zmienia
|
||
}
|
||
|
||
// sprawdzanie zdarze<7A> semafor<6F>w i ogranicze<7A> szlakowych
|
||
void TController::SetProximityVelocity(double dist, double vel, const vector3 *pos)
|
||
{ // Ra:przeslanie do AI pr<70>dko<6B>ci
|
||
/*
|
||
//!!!! zast<73>pi<70> prawid<69>ow<6F> reakcj<63> AI na SetProximityVelocity !!!!
|
||
if (vel==0)
|
||
{//je<6A>li zatrzymanie, to zmniejszamy dystans o 10m
|
||
dist-=10.0;
|
||
};
|
||
if (dist<0.0) dist=0.0;
|
||
if ((vel<0)?true:dist>0.1*(MoverParameters->Vel*MoverParameters->Vel-vel*vel)+50)
|
||
{//je<6A>li jest dalej od umownej drogi hamowania
|
||
*/
|
||
PutCommand("SetProximityVelocity", dist, vel, pos);
|
||
/*
|
||
}
|
||
else
|
||
{//je<6A>li jest zagro<72>enie, <20>e przekroczy
|
||
Mechanik->SetVelocity(floor(0.2*sqrt(dist)+vel),vel,stopError);
|
||
}
|
||
*/
|
||
}
|
||
|
||
TCommandType TController::BackwardScan()
|
||
{ // sprawdzanie zdarze<7A> semafor<6F>w z ty<74>u pojazdu, zwraca komend<6E>
|
||
// dzi<7A>ki temu b<>dzie mo<6D>na stawa<77> za wskazanym sygnalizatorem, a zw<7A>aszcza je<6A>li b<>dzie jazda
|
||
// na kozio<69>
|
||
// ograniczenia pr<70>dko<6B>ci nie s<> wtedy istotne, r<>wnie<69> koniec toru jest do niczego nie
|
||
// przydatny
|
||
// zwraca true, je<6A>li nale<6C>y odwr<77>ci<63> kierunek jazdy pojazdu
|
||
if ((OrderList[OrderPos] & ~(Shunt | Connect)))
|
||
return cm_Unknown; // skanowanie sygna<6E><61>w tylko gdy jedzie w trybie manewrowym albo czeka na
|
||
// rozkazy
|
||
vector3 sl;
|
||
int startdir =
|
||
-pVehicles[0]->DirectionGet(); // kierunek jazdy wzgl<67>dem sprz<72>g<EFBFBD>w pojazdu na czele
|
||
if (startdir == 0) // je<6A>li kabina i kierunek nie jest okre<72>lony
|
||
return cm_Unknown; // nie robimy nic
|
||
double scandir =
|
||
startdir * pVehicles[0]->RaDirectionGet(); // szukamy od pierwszej osi w wybranym kierunku
|
||
if (scandir !=
|
||
0.0) // skanowanie toru w poszukiwaniu event<6E>w GetValues (PutValues nie s<> przydatne)
|
||
{ // Ra: przy wstecznym skanowaniu pr<70>dko<6B><6F> nie ma znaczenia
|
||
// scanback=pVehicles[1]->NextDistance(fLength+1000.0); //odleg<65>o<EFBFBD><6F> do nast<73>pnego pojazdu,
|
||
// 1000 gdy nic nie ma
|
||
double scanmax = 1000; // 1000m do ty<74>u, <20>eby widzia<69> przeciwny koniec stacji
|
||
double scandist = scanmax; // zmodyfikuje na rzeczywi<77>cie przeskanowane
|
||
TEvent *e = NULL; // event potencjalnie od semafora
|
||
// opcjonalnie mo<6D>e by<62> skanowanie od "wska<6B>nika" z przodu, np. W5, Tm=Ms1, koniec toru
|
||
TTrack *scantrack = BackwardTraceRoute(scandist, scandir, pVehicles[0]->RaTrackGet(),
|
||
e); // wg drugiej osi w kierunku ruchu
|
||
vector3 dir = startdir * pVehicles[0]->VectorFront(); // wektor w kierunku jazdy/szukania
|
||
if (!scantrack) // je<6A>li wstecz wykryto koniec toru
|
||
return cm_Unknown; // to raczej nic si<73> nie da w takiej sytuacji zrobi<62>
|
||
else
|
||
{ // a je<6A>li s<> dalej tory
|
||
double vmechmax; // pr<70>dko<6B><6F> ustawiona semaforem
|
||
if (e)
|
||
{ // je<6A>li jest jaki<6B> sygna<6E> na widoku
|
||
#if LOGBACKSCAN
|
||
AnsiString edir =
|
||
pVehicle->asName + " - " + AnsiString((scandir > 0) ? "Event2 " : "Event1 ");
|
||
#endif
|
||
// najpierw sprawdzamy, czy semafor czy inny znak zosta<74> przejechany
|
||
vector3 pos = pVehicles[1]->RearPosition(); // pozycja ty<74>u
|
||
vector3 sem; // wektor do sygna<6E>u
|
||
if (e->Type == tp_GetValues)
|
||
{ // przes<65>a<EFBFBD> info o zbli<6C>aj<61>cym si<73> semaforze
|
||
#if LOGBACKSCAN
|
||
edir += "(" + (e->Params[8].asGroundNode->asName) + "): ";
|
||
#endif
|
||
sl = e->PositionGet(); // po<70>o<EFBFBD>enie kom<6F>rki pami<6D>ci
|
||
sem = sl - pos; // wektor do kom<6F>rki pami<6D>ci od ko<6B>ca sk<73>adu
|
||
// sem=e->Params[8].asGroundNode->pCenter-pos; //wektor do kom<6F>rki pami<6D>ci
|
||
if (dir.x * sem.x + dir.z * sem.z < 0) // je<6A>li zosta<74> mini<6E>ty
|
||
// if ((mvOccupied->CategoryFlag&1)?(VelNext!=0.0):true) //dla poci<63>gu wymagany
|
||
// sygna<6E> zezwalaj<61>cy
|
||
{ // iloczyn skalarny jest ujemny, gdy sygna<6E> stoi z ty<74>u
|
||
#if LOGBACKSCAN
|
||
WriteLog(edir + "- ignored as not passed yet");
|
||
#endif
|
||
return cm_Unknown; // nic
|
||
}
|
||
vmechmax = e->ValueGet(1); // pr<70>dko<6B><6F> przy tym semaforze
|
||
// przeliczamy odleg<65>o<EFBFBD><6F> od semafora - potrzebne by by<62>y wsp<73><70>rz<72>dne pocz<63>tku
|
||
// sk<73>adu
|
||
// scandist=(pos-e->Params[8].asGroundNode->pCenter).Length()-0.5*mvOccupied->Dim.L-10;
|
||
// //10m luzu
|
||
scandist = sem.Length() - 2; // 2m luzu przy manewrach wystarczy
|
||
if (scandist < 0)
|
||
scandist = 0; // ujemnych nie ma po co wysy<73>a<EFBFBD>
|
||
bool move = false; // czy AI w trybie manewerowym ma doci<63>gn<67><6E> pod S1
|
||
if (e->Command() == cm_SetVelocity)
|
||
if ((vmechmax == 0.0) ? (OrderCurrentGet() & (Shunt | Connect)) :
|
||
(OrderCurrentGet() &
|
||
Connect)) // przy podczepianiu ignorowa<77> wyjazd?
|
||
move = true; // AI w trybie manewerowym ma doci<63>gn<67><6E> pod S1
|
||
else
|
||
{ //
|
||
if ((scandist > fMinProximityDist) ?
|
||
(mvOccupied->Vel > 0.0) && (OrderCurrentGet() != Shunt) :
|
||
false)
|
||
{ // je<6A>li semafor jest daleko, a pojazd jedzie, to informujemy o
|
||
// zmianie pr<70>dko<6B>ci
|
||
// je<6A>li jedzie manewrowo, musi dosta<74> SetVelocity, <20>eby sie na poci<63>gowy prze<7A><65>czy<7A>
|
||
// Mechanik->PutCommand("SetProximityVelocity",scandist,vmechmax,sl);
|
||
#if LOGBACKSCAN
|
||
// WriteLog(edir+"SetProximityVelocity "+AnsiString(scandist)+"
|
||
// "+AnsiString(vmechmax));
|
||
WriteLog(edir);
|
||
#endif
|
||
// SetProximityVelocity(scandist,vmechmax,&sl);
|
||
return (vmechmax > 0) ? cm_SetVelocity : cm_Unknown;
|
||
}
|
||
else // ustawiamy pr<70>dko<6B><6F> tylko wtedy, gdy ma ruszy<7A>, stan<61><6E> albo ma
|
||
// sta<74>
|
||
// if ((MoverParameters->Vel==0.0)||(vmechmax==0.0)) //je<6A>li stoi lub ma
|
||
// stan<61><6E>/sta<74>
|
||
{ // semafor na tym torze albo lokomtywa stoi, a ma ruszy<7A>, albo ma
|
||
// stan<61><6E>, albo nie rusza<7A>
|
||
// stop trzeba powtarza<7A>, bo inaczej zatr<74>bi i pojedzie sam
|
||
// PutCommand("SetVelocity",vmechmax,e->Params[9].asMemCell->Value2(),&sl,stopSem);
|
||
#if LOGBACKSCAN
|
||
WriteLog(edir + "SetVelocity " + AnsiString(vmechmax) + " " +
|
||
AnsiString(e->Params[9].asMemCell->Value2()));
|
||
#endif
|
||
return (vmechmax > 0) ? cm_SetVelocity : cm_Unknown;
|
||
}
|
||
}
|
||
if (OrderCurrentGet() ? OrderCurrentGet() & (Shunt | Connect) :
|
||
true) // w Wait_for_orders te<74> widzi tarcze
|
||
{ // reakcja AI w trybie manewrowym dodatkowo na sygna<6E>y manewrowe
|
||
if (move ? true : e->Command() == cm_ShuntVelocity)
|
||
{ // je<6A>li powy<77>ej by<62>o SetVelocity 0 0, to doci<63>gamy pod S1
|
||
if ((scandist > fMinProximityDist) ?
|
||
(mvOccupied->Vel > 0.0) || (vmechmax == 0.0) :
|
||
false)
|
||
{ // je<6A>li tarcza jest daleko, to:
|
||
//- jesli pojazd jedzie, to informujemy o zmianie pr<70>dko<6B>ci
|
||
//- je<6A>li stoi, to z w<>asnej inicjatywy mo<6D>e podjecha<68> pod zamkni<6E>t<EFBFBD>
|
||
// tarcz<63>
|
||
if (mvOccupied->Vel > 0.0) // tylko je<6A>li jedzie
|
||
{ // Mechanik->PutCommand("SetProximityVelocity",scandist,vmechmax,sl);
|
||
#if LOGBACKSCAN
|
||
// WriteLog(edir+"SetProximityVelocity "+AnsiString(scandist)+"
|
||
// "+AnsiString(vmechmax));
|
||
WriteLog(edir);
|
||
#endif
|
||
// SetProximityVelocity(scandist,vmechmax,&sl);
|
||
return (iDrivigFlags & moveTrackEnd) ?
|
||
cm_ChangeDirection :
|
||
cm_Unknown; // je<6A>li jedzie na W5 albo koniec toru,
|
||
// to mo<6D>na zmieni<6E> kierunek
|
||
}
|
||
}
|
||
else // ustawiamy pr<70>dko<6B><6F> tylko wtedy, gdy ma ruszy<7A>, albo stan<61><6E> albo
|
||
// ma sta<74> pod tarcz<63>
|
||
{ // stop trzeba powtarza<7A>, bo inaczej zatr<74>bi i pojedzie sam
|
||
// if ((MoverParameters->Vel==0.0)||(vmechmax==0.0)) //je<6A>li jedzie
|
||
// lub ma stan<61><6E>/sta<74>
|
||
{ // nie dostanie komendy je<6A>li jedzie i ma jecha<68>
|
||
// PutCommand("ShuntVelocity",vmechmax,e->Params[9].asMemCell->Value2(),&sl,stopSem);
|
||
#if LOGBACKSCAN
|
||
WriteLog(edir + "ShuntVelocity " + AnsiString(vmechmax) + " " +
|
||
AnsiString(e->ValueGet(2)));
|
||
#endif
|
||
return (vmechmax > 0) ? cm_ShuntVelocity : cm_Unknown;
|
||
}
|
||
}
|
||
if ((vmechmax != 0.0) && (scandist < 100.0))
|
||
{ // je<6A>li Tm w odleg<65>o<EFBFBD>ci do 100m podaje zezwolenie na jazd<7A>, to od
|
||
// razu j<> ignorujemy, aby m<>c szuka<6B> kolejnej
|
||
// eSignSkip=e; //wtedy uznajemy ignorowan<61> przy poszukiwaniu nowej
|
||
#if LOGBACKSCAN
|
||
WriteLog(edir + "- will be ignored due to Ms2");
|
||
#endif
|
||
return (vmechmax > 0) ? cm_ShuntVelocity : cm_Unknown;
|
||
}
|
||
} // if (move?...
|
||
} // if (OrderCurrentGet()==Shunt)
|
||
if (!e->bEnabled) // je<6A>li skanowany
|
||
if (e->StopCommand()) // a pod<6F><64>czona kom<6F>rka ma komend<6E>
|
||
return cm_Command; // to te<74> si<73> obr<62>ci<63>
|
||
} // if (e->Type==tp_GetValues)
|
||
} // if (e)
|
||
} // if (scantrack)
|
||
} // if (scandir!=0.0)
|
||
return cm_Unknown; // nic
|
||
};
|
||
|
||
std::string TController::NextStop()
|
||
{ // informacja o nast<73>pnym zatrzymaniu, wy<77>wietlane pod [F1]
|
||
if (asNextStop.length() < 19)
|
||
return ""; // nie zawiera nazwy stacji, gdy dojecha<68> do ko<6B>ca
|
||
// doda<64> godzin<69> odjazdu
|
||
if (!TrainParams)
|
||
return ""; // tu nie powinno nigdy wej<65><6A>
|
||
TMTableLine *t = TrainParams->TimeTable + TrainParams->StationIndex;
|
||
if (t->Dh >= 0) // je<6A>li jest godzina odjazdu
|
||
return asNextStop.substr(19, 30) + " " + to_string(t->Dh) + ":" +
|
||
to_string(t->Dm); // odjazd
|
||
else if (t->Ah >= 0) // przyjazd
|
||
return asNextStop.substr(19, 30) + " (" + to_string(t->Ah) + ":" +
|
||
to_string(t->Am) + ")"; // przyjazd
|
||
return "";
|
||
};
|
||
|
||
//-----------koniec skanowania semaforow
|
||
|
||
void TController::TakeControl(bool yes)
|
||
{ // przej<65>cie kontroli przez AI albo oddanie
|
||
if (AIControllFlag == yes)
|
||
return; // ju<6A> jest jak ma by<62>
|
||
if (yes) //<2F>eby nie wykonywa<77> dwa razy
|
||
{ // teraz AI prowadzi
|
||
AIControllFlag = AIdriver;
|
||
pVehicle->Controller = AIdriver;
|
||
iDirection = 0; // kierunek jazdy trzeba dopiero zgadn<64><6E>
|
||
// gdy zgaszone <20>wiat<61>a, flaga podje<6A>d<EFBFBD>ania pod semafory pozostaje bez zmiany
|
||
if (OrderCurrentGet()) // je<6A>li co<63> robi
|
||
PrepareEngine(); // niech sprawdzi stan silnika
|
||
else // je<6A>li nic nie robi
|
||
if (pVehicle->iLights[mvOccupied->CabNo < 0 ? 1 : 0] &
|
||
21) // kt<6B>re<72> ze <20>wiate<74> zapalone?
|
||
{ // od wersji 357 oczekujemy podania komend dla AI przez sceneri<72>
|
||
OrderNext(Prepare_engine);
|
||
if (pVehicle->iLights[mvOccupied->CabNo < 0 ? 1 : 0] & 4) // g<>rne <20>wiat<61>o zapalone
|
||
OrderNext(Obey_train); // jazda poci<63>gowa
|
||
else
|
||
OrderNext(Shunt); // jazda manewrowa
|
||
if (mvOccupied->Vel >= 1.0) // je<6A>li jedzie (dla 0.1 ma sta<74>)
|
||
iDrivigFlags &= ~moveStopHere; // to ma nie czeka<6B> na sygna<6E>, tylko jecha<68>
|
||
else
|
||
iDrivigFlags |= moveStopHere; // a jak stoi, to niech czeka
|
||
}
|
||
/* od wersji 357 oczekujemy podania komend dla AI przez sceneri<72>
|
||
if (OrderCurrentGet())
|
||
{if (OrderCurrentGet()<Shunt)
|
||
{OrderNext(Prepare_engine);
|
||
if (pVehicle->iLights[mvOccupied->CabNo<0?1:0]&4) //g<>rne <20>wiat<61>o
|
||
OrderNext(Obey_train); //jazda poci<63>gowa
|
||
else
|
||
OrderNext(Shunt); //jazda manewrowa
|
||
}
|
||
}
|
||
else //je<6A>li jest w stanie Wait_for_orders
|
||
JumpToFirstOrder(); //uruchomienie?
|
||
// czy dac ponizsze? to problematyczne
|
||
//SetVelocity(pVehicle->GetVelocity(),-1); //utrzymanie dotychczasowej?
|
||
if (pVehicle->GetVelocity()>0.0)
|
||
SetVelocity(-1,-1); //AI ustali sobie odpowiedni<6E> pr<70>dko<6B><6F>
|
||
*/
|
||
// Activation(); //przeniesie u<>ytkownika w ostatnio wybranym kierunku
|
||
CheckVehicles(); // ustawienie <20>wiate<74>
|
||
TableClear(); // ponowne utworzenie tabelki, bo cz<63>owiek m<>g<EFBFBD> pojecha<68> niezgodnie z
|
||
// sygna<6E>ami
|
||
}
|
||
else
|
||
{ // a teraz u<>ytkownik
|
||
AIControllFlag = Humandriver;
|
||
pVehicle->Controller = Humandriver;
|
||
}
|
||
};
|
||
|
||
void TController::DirectionForward(bool forward)
|
||
{ // ustawienie jazdy do przodu dla true i do ty<74>u dla false (zale<6C>y od kabiny)
|
||
while (mvControlling->MainCtrlPos) // samo zap<61>tlenie DecSpeed() nie wystarcza
|
||
DecSpeed(true); // wymuszenie zerowania nastawnika jazdy, inaczej si<73> mo<6D>e zawiesi<73>
|
||
if (forward)
|
||
while (mvOccupied->ActiveDir <= 0)
|
||
mvOccupied->DirectionForward(); // do przodu w obecnej kabinie
|
||
else
|
||
while (mvOccupied->ActiveDir >= 0)
|
||
mvOccupied->DirectionBackward(); // do ty<74>u w obecnej kabinie
|
||
if (mvOccupied->EngineType == DieselEngine) // specjalnie dla SN61
|
||
if (iDrivigFlags & moveActive) // je<6A>li by<62> ju<6A> odpalony
|
||
if (mvControlling->RList[mvControlling->MainCtrlPos].Mn == 0)
|
||
mvControlling->IncMainCtrl(1); //<2F>eby nie zgas<61>
|
||
};
|
||
|
||
std::string TController::Relation()
|
||
{ // zwraca relacj<63> poci<63>gu
|
||
return TrainParams->ShowRelation();
|
||
};
|
||
|
||
std::string TController::TrainName()
|
||
{ // zwraca numer poci<63>gu
|
||
return TrainParams->TrainName;
|
||
};
|
||
|
||
int TController::StationCount()
|
||
{ // zwraca ilo<6C><6F> stacji (miejsc zatrzymania)
|
||
return TrainParams->StationCount;
|
||
};
|
||
|
||
int TController::StationIndex()
|
||
{ // zwraca indeks aktualnej stacji (miejsca zatrzymania)
|
||
return TrainParams->StationIndex;
|
||
};
|
||
|
||
bool TController::IsStop()
|
||
{ // informuje, czy jest zatrzymanie na najbli<6C>szej stacji
|
||
return TrainParams->IsStop();
|
||
};
|
||
|
||
void TController::MoveTo(TDynamicObject *to)
|
||
{ // przesuni<6E>cie AI do innego pojazdu (przy zmianie kabiny)
|
||
// mvOccupied->CabDeactivisation(); //wy<77><79>czenie kabiny w opuszczanym
|
||
pVehicle->Mechanik = to->Mechanik; //<2F>eby si<73> zamieni<6E>y, jak jest jakie<69> drugie
|
||
pVehicle = to;
|
||
ControllingSet(); // utworzenie po<70><6F>czenia do sterowanego pojazdu
|
||
pVehicle->Mechanik = this;
|
||
// iDirection=0; //kierunek jazdy trzeba dopiero zgadn<64><6E>
|
||
};
|
||
|
||
void TController::ControllingSet()
|
||
{ // znajduje cz<63>on do sterowania w EZT b<>dzie to silnikowy
|
||
// problematyczne jest sterowanie z cz<63>onu biernego, dlatego damy AI silnikowy
|
||
// dzi<7A>ki temu b<>dzie wirtualna kabina w silnikowym, dzia<69>aj<61>ca w rozrz<72>dczym
|
||
// w plikach FIZ zosta<74>y zgubione ujemne maski sprz<72>g<EFBFBD>w, st<73>d problemy z EZT
|
||
mvOccupied = pVehicle->MoverParameters; // domy<6D>lny skr<6B>t do obiektu parametr<74>w
|
||
mvControlling = pVehicle->ControlledFind()->MoverParameters; // poszukiwanie cz<63>onu sterowanego
|
||
};
|
||
|
||
std::string TController::TableText(int i)
|
||
{ // pozycja tabelki pr<70>dko<6B>ci
|
||
i = (iFirst + i) % iSpeedTableSize; // numer pozycji
|
||
if (i != iLast) // w (iLast) znajduje si<73> kolejny tor do przeskanowania, ale nie jest ona
|
||
// aktywn<77>
|
||
return sSpeedTable[i].TableText();
|
||
return ""; // wska<6B>nik ko<6B>ca
|
||
};
|
||
|
||
int TController::CrossRoute(TTrack *tr)
|
||
{ // zwraca numer segmentu dla skrzy<7A>owania (tr)
|
||
// po<70><6F>dany numer segmentu jest okre<72>lany podczas skanowania drogi
|
||
// droga powinna by<62> okre<72>lona sposobem przejazdu przez skrzy<7A>owania albo wsp<73><70>rz<72>dnymi miejsca
|
||
// docelowego
|
||
for (int i = iFirst; i != iLast; i = (i + 1) % iSpeedTableSize)
|
||
{ // trzeba przejrze<7A> tabel<65> skanowania w poszukiwaniu (tr)
|
||
// i jak si<73> znajdzie, to zwr<77>ci<63> zapami<6D>tany numer segmentu i kierunek przejazdu
|
||
// (-6..-1,1..6)
|
||
if ((sSpeedTable[i].iFlags & 3) == 3) // je<6A>li pozycja istotna (1) oraz odcinek (2)
|
||
if (sSpeedTable[i].trTrack == tr) // je<6A>li pozycja odpowiadaj<61>ca skrzy<7A>owaniu (tr)
|
||
return (sSpeedTable[i].iFlags >> 28); // najstarsze 4 bity jako liczba -8..7
|
||
}
|
||
return 0; // nic nie znaleziono?
|
||
};
|
||
|
||
void TController::RouteSwitch(int d)
|
||
{ // ustawienie kierunku jazdy z kabiny
|
||
d &= 3;
|
||
if (d)
|
||
if (iRouteWanted != d)
|
||
{ // nowy kierunek
|
||
iRouteWanted = d; // zapami<6D>tanie
|
||
if (mvOccupied->CategoryFlag & 2) // je<6A>li samoch<63>d
|
||
for (int i = iFirst; i != iLast; i = (i + 1) % iSpeedTableSize)
|
||
{ // szukanie pierwszego skrzy<7A>owania i resetowanie kierunku na nim
|
||
if ((sSpeedTable[i].iFlags & 3) ==
|
||
3) // je<6A>li pozycja istotna (1) oraz odcinek (2)
|
||
if ((sSpeedTable[i].iFlags & 32) == 0) // odcinek nie mo<6D>e by<62> mini<6E>tym
|
||
if (sSpeedTable[i].trTrack->eType == tt_Cross) // je<6A>li skrzy<7A>owanie
|
||
{ // obci<63>cie tabelki skanowania przed skrzy<7A>owaniem, aby ponownie
|
||
// wybra<72> drog<6F>
|
||
iLast = i - 1; // ponowne skanowanie skrzy<7A>owania (w zwrotnicach
|
||
// jest iLast=i, ale tam jest pro<72>ciej)
|
||
if (iLast < 0)
|
||
iLast += iSpeedTableSize; // bo tabelka jest zap<61>tlona
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
std::string TController::OwnerName()
|
||
{
|
||
return pVehicle ? pVehicle->MoverParameters->Name : string("none");
|
||
};
|