build 170825. tweaks and fixes to AI brake handling, scan table distance calculation fix

This commit is contained in:
tmj-fstate
2017-08-25 21:06:43 +02:00
parent 42aab52038
commit 110bdf63bb
5 changed files with 138 additions and 163 deletions

View File

@@ -222,8 +222,8 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len )
// może być NULL, jeśli koniec toru (????)
vPos =
(iFlags & spReverse) ?
trTrack->CurrentSegment()->FastGetPoint_0() :
trTrack->CurrentSegment()->FastGetPoint_1(); // drugi koniec istotny
trTrack->CurrentSegment()->FastGetPoint_1() : // drugi koniec istotny
trTrack->CurrentSegment()->FastGetPoint_0();
}
}
}
@@ -1250,11 +1250,15 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
else {
// przyspieszenie: ujemne, gdy trzeba hamować
a = ( v * v - mvOccupied->Vel * mvOccupied->Vel ) / ( 25.92 * d );
auto const brakingdistance = fBrakeDist * braking_distance_multiplier( v );
if( brakingdistance > 0.0 ) {
// maintain desired acc while we have enough room to brake safely, when close enough start paying attention
// try to make a smooth transition instead of sharp change
a = interpolate( a, AccPreferred, clamp( ( d - brakingdistance ) / brakingdistance, 0.0, 1.0 ) );
if( ( mvOccupied->Vel < v )
|| ( v == 0.0 ) ) {
// if we're going slower than the target velocity and there's enough room for safe stop, speed up
auto const brakingdistance = fBrakeDist * braking_distance_multiplier( v );
if( brakingdistance > 0.0 ) {
// maintain desired acc while we have enough room to brake safely, when close enough start paying attention
// try to make a smooth transition instead of sharp change
a = interpolate( a, AccPreferred, clamp( ( d - brakingdistance ) / brakingdistance, 0.0, 1.0 ) );
}
}
if( ( d < fMinProximityDist )
&& ( v < fVelDes ) ) {
@@ -3850,6 +3854,12 @@ bool TController::UpdateSituation(double dt)
// na jaką odleglość i z jaką predkością ma podjechać
fMinProximityDist = 5.0;
fMaxProximityDist = 10.0; //[m]
if( pVehicles[ 0 ] != pVehicles[ 1 ] ) {
// for larger consists increase margins to account for slower braking etc
// NOTE: this will affect also multi-unit vehicles TBD: is this what we want?
fMinProximityDist *= 2.0;
fMaxProximityDist *= 2.0;
}
fVelPlus = 2.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania
// margines prędkości powodujący załączenie napędu
// były problemy z jazdą np. 3km/h podczas ładowania wagonów
@@ -4062,10 +4072,11 @@ bool TController::UpdateSituation(double dt)
// no chyba żeby to uwzgldnić już w (ActualProximityDist)
VelDesired = fVelMax; // wstępnie prędkość maksymalna dla pojazdu(-ów), będzie
// następnie ograniczana
if (TrainParams) // jeśli ma rozkład
if (TrainParams->TTVmax > 0.0) // i ograniczenie w rozkładzie
VelDesired = Global::Min0RSpeed(VelDesired,
TrainParams->TTVmax); // to nie przekraczać rozkladowej
if( ( TrainParams )
&& ( TrainParams->TTVmax > 0.0 ) ) {
// jeśli ma rozkład i ograniczenie w rozkładzie to nie przekraczać rozkladowej
VelDesired = Global::Min0RSpeed( VelDesired, TrainParams->TTVmax );
}
SetDriverPsyche(); // ustawia AccPreferred (potrzebne tu?)
// Ra: odczyt (ActualProximityDist), (VelNext) i (AccPreferred) z tabelki prędkosci
AccDesired = AccPreferred; // AccPreferred wynika z osobowości mechanika
@@ -4131,14 +4142,11 @@ bool TController::UpdateSituation(double dt)
// i dopiero wtedy zmienić kierunek jazdy, oczekując podania
// prędkości >0.5
if (comm == cm_Command) // jeśli komenda Shunt
iDrivigFlags |=
moveStopHere; // to ją odbierz bez przemieszczania się (np.
iDrivigFlags |= moveStopHere; // to ją odbierz bez przemieszczania się (np.
// odczep wagony po dopchnięciu do końca toru)
iDirectionOrder = -iDirection; // zmiana kierunku jazdy
OrderList[OrderPos] = TOrders(OrderList[OrderPos] |
Change_direction); // zmiana kierunku
// bez psucia
// kolejnych komend
// zmiana kierunku bez psucia kolejnych komend
OrderList[OrderPos] = TOrders(OrderList[OrderPos] | Change_direction);
}
}
double vel = mvOccupied->Vel; // prędkość w kierunku jazdy
@@ -4297,11 +4305,11 @@ bool TController::UpdateSituation(double dt)
}
}
}
if (mvOccupied->V == 0.0)
AbsAccS = fAccGravity; // Ra 2014-03: jesli skład stoi, to działa na niego
// składowa styczna grawitacji
else
{
if( mvOccupied->V == 0.0 ) {
// Ra 2014-03: jesli skład stoi, to działa na niego składowa styczna grawitacji
AbsAccS = fAccGravity;
}
else {
AbsAccS = 0;
TDynamicObject *d = pVehicles[0]; // pojazd na czele składu
while (d)
@@ -4310,15 +4318,9 @@ bool TController::UpdateSituation(double dt)
d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła)
}
AbsAccS /= fMass;
//AbsAccS = iDirection * mvOccupied->AccS; // przyspieszenie chwilowe, liczone
}
AbsAccS_pub = AbsAccS;
// jako różnica skierowanej prędkości w
// czasie
// if (mvOccupied->V<0.0) AbsAccS=-AbsAccS; //Ra 2014-03: to trzeba przemyśleć
// if (vel<0) //jeżeli się stacza w tył; 2014-03: to jest bez sensu, bo vel>=0
// AbsAccS=-AbsAccS; //to przyspieszenie też działa wtedy w nieodpowiednią stronę
// AbsAccS+=fAccGravity; //wypadkowe przyspieszenie (czy to ma sens?)
#if LOGVELOCITY
// WriteLog("VelDesired="+AnsiString(VelDesired)+",
// VelSignal="+AnsiString(VelSignal));
@@ -4343,10 +4345,11 @@ bool TController::UpdateSituation(double dt)
// jeśli jedzie
if( ( vel < VelNext )
&& ( ActualProximityDist > fMaxProximityDist * ( 1.0 + 0.1 * vel ) ) ) {
// dojedz do semafora/przeszkody
// jeśli jedzie wolniej niż można i jest wystarczająco daleko, to można przyspieszyć
if (AccPreferred > 0.0) // jeśli nie ma zawalidrogi
if( AccPreferred > 0.0 ) {
// jeśli nie ma zawalidrogi dojedz do semafora/przeszkody
AccDesired = AccPreferred;
}
}
else if (ActualProximityDist > fMinProximityDist) {
// jedzie szybciej, niż trzeba na końcu ActualProximityDist, ale jeszcze jest daleko
@@ -4360,84 +4363,27 @@ bool TController::UpdateSituation(double dt)
AccDesired = std::min( AccDesired, fAccThreshold );
}
}
else if ((vel < VelNext + fVelPlus)||((vel<VelNext+2*fVelPlus)&&
(vel*vel<(VelNext + fVelPlus)*(VelNext + fVelPlus)-12.96*ActualProximityDist*std::min(0.0,AbsAccS)))) // jeśli niewielkie przekroczenie
{ // AccDesired=0.0;
AccDesired = 0.01; // proteza trochę: to
}
else if( (mvControlling->CategoryFlag == 1) && (ActualProximityDist*25.92*fBrake_a0[0] > 2*vel*vel))
{ // jeśli ma stanąć, a mieści się w drodze hamowania
AccDesired = AccPreferred;
}
/*
else if ((vel < VelNext + 20.0)&&(false)) // dwustopniowe hamowanie - niski przy małej różnicy
{ // jeśli jedzie wolniej niż VelNext+35km/h //Ra: 40, żeby nie
// kombinował na zwrotnicach
if (VelNext == 0.0)
{ // jeśli ma się zatrzymać, musi być to robione precyzyjnie i skutecznie
if (ActualProximityDist > fBrakeDist)
{ // jeśli ma stanąć, a mieści się w drodze hamowania
if (vel < 10.0) // jeśli prędkość jest łatwa do zatrzymania
{ // tu jest trochę problem, bo do punktu zatrzymania dobija
// na raty
// AccDesired=AccDesired<0.0?0.0:0.1*AccPreferred;
AccDesired = AccPreferred; // proteza trochę; jak tu
// wychodzi 0.05, to loki
// mają problem utrzymać
// 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ę
// dobijają do siebie
else
AccDesired = 0.0;
}
else // 25.92 (=3.6*3.6*2) - przelicznik z km/h na m/s
// niech nie hamuje, chyba że coś z przodu
AccDesired = -(vel * vel) /
(25.92 * (ActualProximityDist +
0.1-0.5*(fMinProximityDist+fMaxProximityDist))); //-fMinProximityDist));//-0.1;
////mniejsze opóźnienie przy małej różnicy
ReactionTime = 0.1; // i orientuj się szybciej, jak masz stanąć
}
else if (vel < VelNext + fVelPlus) // jeśli niewielkie
// przekroczenie, ale ma jechać
AccDesired = std::min( 0.0, AccPreferred ); // to olej (zacznij luzować)
else
{ // jeśli większe przekroczenie niż fVelPlus [km/h], ale ma jechać
// Ra 2F1I: jak było (VelNext+fVelPlus) tu, to hamował zbyt
// późno przed 40, a potem zbyt mocno i zwalniał do 30
AccDesired = (VelNext * VelNext - vel * vel) /
(25.92 * ActualProximityDist +
0.1); // mniejsze opóźnienie przy małej różnicy
if( ActualProximityDist < fMaxProximityDist ) {
// i orientuj się szybciej, jeśli w krytycznym przedziale
ReactionTime = 0.1;
}
}
}
*/
else {
// przy dużej różnicy wysoki stopień (1,00 potrzebnego opoznienia)
double dist = 0;// (VelNext * VelNext - (VelNext + 20) * (VelNext + 20)) / (25.92)*(-1 / fBrake_a0[0] - 1 / fAccThreshold);
// ensure some minimal coasting speed, otherwise a vehicle entering this zone at very low speed will be crawling forever
AccDesired =
auto const brakingpointoffset = VelNext * braking_distance_multiplier( VelNext );
AccDesired = std::min(
AccDesired,
( VelNext * VelNext - vel * vel )
/ ( 25.92
* std::max(
ActualProximityDist - VelNext - dist,
ActualProximityDist - brakingpointoffset,
std::min(
ActualProximityDist,
VelNext + dist ) )
+ 0.1 ); // najpierw hamuje mocniej, potem zluzuje
brakingpointoffset ) )
+ 0.1 ) ); // najpierw hamuje mocniej, potem zluzuje
}
AccDesired = std::min( AccDesired, AccPreferred );
}
else {
// jest bliżej niż fMinProximityDist
VelDesired = Global::Min0RSpeed( VelDesired, VelNext ); // utrzymuj predkosc bo juz blisko
// utrzymuj predkosc bo juz blisko
VelDesired = Global::Min0RSpeed( VelDesired, VelNext );
if( vel <= VelNext + fVelPlus ) {
// jeśli niewielkie przekroczenie, ale ma jechać
AccDesired = std::max( 0.0, AccPreferred ); // to olej (zacznij luzować)
@@ -4474,21 +4420,38 @@ bool TController::UpdateSituation(double dt)
}
}
}
else // gdy jedzie wolniej niż potrzeba, albo nie ma przeszkód na drodze
AccDesired = (VelDesired != 0.0 ? AccPreferred : -0.01); // normalna jazda
else {
// gdy jedzie wolniej niż potrzeba, albo nie ma przeszkód na drodze
// normalna jazda
AccDesired = (
VelDesired != 0.0 ?
AccPreferred :
-0.01 );
}
// 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 = std::min(AccDesired,-0.9); // hamuj solidnie
else if ((vel < VelDesired + fVelPlus)) // o 5 km/h to olej
{
if ((AccDesired > 0.0))
AccDesired = 0.0;
if( vel > VelDesired ) {
// jesli jedzie za szybko do AKTUALNEGO
if( VelDesired == 0.0 ) {
// jesli stoj, to hamuj, ale i tak juz za pozno :)
AccDesired = std::min( AccDesired, -0.9 ); // hamuj solidnie
}
else
AccDesired = std::min(AccDesired,fBrake_a0[0]); // hamuj tak średnio
else {
// slow down, not full stop
if( vel > ( VelDesired + fVelPlus ) ) {
// hamuj tak średnio
AccDesired = std::min( AccDesired, -fBrake_a0[ 0 ] * 0.5 );
}
else {
// o 5 km/h to olej (zacznij luzować)
AccDesired = std::min(
AccDesired, // but don't override decceleration for VelNext
std::max( 0.0, AccPreferred ) );
}
}
}
// koniec predkosci aktualnej
#ifdef DEBUGFAC
if (fAccThreshold > -0.3) // bez sensu, ale dla towarowych korzystnie
{ // Ra 2014-03: to nie uwzględnia odległości i zaczyna hamować, jak tylko zobaczy
@@ -4736,26 +4699,23 @@ bool TController::UpdateSituation(double dt)
} // type & dt_ezt
else {
// a stara wersja w miarę dobrze działa na składy wagonowe
if( ( VelNext == 0.0 )
|| ( vel > VelNext + fVelPlus ) ) {
if( ( ( fAccGravity < -0.05 ) && ( vel < 0.0 ) )
|| ( ( AccDesired < fAccGravity - 0.1 ) && ( AbsAccS > AccDesired + fBrake_a1[ 0 ] ) ) ) {
// u góry ustawia się hamowanie na fAccThreshold
if( ( fBrakeTime < 0.0 )
|| ( AccDesired < fAccGravity - 0.3 )
|| ( mvOccupied->BrakeCtrlPos <= 0 ) ) {
// jeśli upłynął czas reakcji hamulca, chyba że nagłe albo luzował
if( true == IncBrake() ) {
fBrakeTime =
3.0
+ 0.5 * ( (
mvOccupied->BrakeDelayFlag > bdelay_G ?
mvOccupied->BrakeDelay[ 1 ] :
mvOccupied->BrakeDelay[ 3 ] )
- 3.0 );
// Ra: ten czas należy zmniejszyć, jeśli czas dojazdu do zatrzymania jest mniejszy
fBrakeTime *= 0.5; // Ra: tymczasowo, bo przeżyna S1
}
if( ( ( fAccGravity < -0.05 ) && ( vel < 0.0 ) )
|| ( ( AccDesired < fAccGravity - 0.1 ) && ( AbsAccS > AccDesired + fBrake_a1[ 0 ] ) ) ) {
// u góry ustawia się hamowanie na fAccThreshold
if( ( fBrakeTime < 0.0 )
|| ( AccDesired < fAccGravity - 0.5 )
|| ( mvOccupied->BrakeCtrlPos <= 0 ) ) {
// jeśli upłynął czas reakcji hamulca, chyba że nagłe albo luzował
if( true == IncBrake() ) {
fBrakeTime =
3.0
+ 0.5 * ( (
mvOccupied->BrakeDelayFlag > bdelay_G ?
mvOccupied->BrakeDelay[ 1 ] :
mvOccupied->BrakeDelay[ 3 ] )
- 3.0 );
// Ra: ten czas należy zmniejszyć, jeśli czas dojazdu do zatrzymania jest mniejszy
fBrakeTime *= 0.5; // Ra: tymczasowo, bo przeżyna S1
}
}
}

View File

@@ -397,12 +397,11 @@ public:
int StationCount();
int StationIndex();
bool IsStop();
bool Primary()
{
return this ? ((iDrivigFlags & movePrimary) != 0) : false;
};
int inline DrivigFlags()
{
inline
bool Primary() const {
return ( ( iDrivigFlags & movePrimary ) != 0 ); };
inline
int DrivigFlags() const {
return iDrivigFlags;
};
void MoveTo(TDynamicObject *to);

View File

@@ -114,15 +114,20 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
{ // omijamy cały ten blok, gdy tor nie ma on żadnych eventów (większość nie ma)
if (fDistance < 0)
{
if (SetFlag(iEventFlag, -1)) // zawsze zeruje flagę sprawdzenia, jak mechanik
// dosiądzie, to się nie wykona
if (Owner->Mechanik->Primary()) // tylko dla jednego członu
// if (TestFlag(iEventFlag,1)) //McZapkie-280503: wyzwalanie event tylko dla
// pojazdow z obsada
if (bPrimary && pCurrentTrack->evEvent1 &&
(!pCurrentTrack->evEvent1->iQueued))
Global::AddToQuery(pCurrentTrack->evEvent1, Owner); // dodanie do
// kolejki
if( SetFlag( iEventFlag, -1 ) ) {
// zawsze zeruje flagę sprawdzenia, jak mechanik dosiądzie, to się nie wykona
if( ( Owner->Mechanik != nullptr )
&& ( Owner->Mechanik->Primary() ) ) {
// tylko dla jednego członu
// McZapkie-280503: wyzwalanie event tylko dla pojazdow z obsada
if( ( bPrimary )
&& ( pCurrentTrack->evEvent1 )
&& ( !pCurrentTrack->evEvent1->iQueued ) ) {
// dodanie do kolejki
Global::AddToQuery( pCurrentTrack->evEvent1, Owner );
}
}
}
// Owner->RaAxleEvent(pCurrentTrack->Event1); //Ra: dynamic zdecyduje, czy dodać do
// kolejki
// if (TestFlag(iEventallFlag,1))
@@ -136,31 +141,42 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
}
else if (fDistance > 0)
{
if (SetFlag(iEventFlag, -2)) // zawsze ustawia flagę sprawdzenia, jak mechanik
if( SetFlag( iEventFlag, -2 ) ) {
// zawsze ustawia flagę sprawdzenia, jak mechanik
// dosiądzie, to się nie wykona
if (Owner->Mechanik->Primary()) // tylko dla jednego członu
// if (TestFlag(iEventFlag,2)) //sprawdzanie jest od razu w pierwszym
// warunku
if (bPrimary && pCurrentTrack->evEvent2 &&
(!pCurrentTrack->evEvent2->iQueued))
Global::AddToQuery(pCurrentTrack->evEvent2, Owner);
if( ( Owner->Mechanik != nullptr )
&& ( Owner->Mechanik->Primary() ) ) {
// tylko dla jednego członu
if( ( bPrimary )
&& ( pCurrentTrack->evEvent2 )
&& ( !pCurrentTrack->evEvent2->iQueued ) ) {
Global::AddToQuery( pCurrentTrack->evEvent2, Owner );
}
}
}
// Owner->RaAxleEvent(pCurrentTrack->Event2); //Ra: dynamic zdecyduje, czy dodać do
// kolejki
// if (TestFlag(iEventallFlag,2))
if (SetFlag(iEventallFlag,
-2)) // sprawdza i zeruje na przyszłość, true jeśli zmieni z 2 na 0
if (bPrimary && pCurrentTrack->evEventall2 &&
(!pCurrentTrack->evEventall2->iQueued))
Global::AddToQuery(pCurrentTrack->evEventall2, Owner);
if( SetFlag( iEventallFlag, -2 ) ) {
// sprawdza i zeruje na przyszłość, true jeśli zmieni z 2 na 0
if( ( bPrimary )
&& ( pCurrentTrack->evEventall2 )
&& ( !pCurrentTrack->evEventall2->iQueued ) ) {
Global::AddToQuery( pCurrentTrack->evEventall2, Owner );
}
}
// Owner->RaAxleEvent(pCurrentTrack->Eventall2); //Ra: dynamic zdecyduje, czy dodać
// do kolejki
}
else // if (fDistance==0) //McZapkie-140602: wyzwalanie zdarzenia gdy pojazd stoi
{
if (Owner->Mechanik->Primary()) // tylko dla jednego członu
if (pCurrentTrack->evEvent0)
if (!pCurrentTrack->evEvent0->iQueued)
Global::AddToQuery(pCurrentTrack->evEvent0, Owner);
if( ( Owner->Mechanik != nullptr )
&& ( Owner->Mechanik->Primary() ) ) {
// tylko dla jednego członu
if( pCurrentTrack->evEvent0 )
if( !pCurrentTrack->evEvent0->iQueued )
Global::AddToQuery( pCurrentTrack->evEvent0, Owner );
}
// Owner->RaAxleEvent(pCurrentTrack->Event0); //Ra: dynamic zdecyduje, czy dodać do
// kolejki
if (pCurrentTrack->evEventall0)

View File

@@ -1314,7 +1314,7 @@ TWorld::Update_UI() {
else if( mover->ActiveDir < 0 ) { uitextline2 += " R"; }
else { uitextline2 += " N"; }
uitextline3 = "Brakes:" + to_string( mover->fBrakeCtrlPos, 1, 5 ) + "+" + std::to_string( mover->LocalBrakePos );
uitextline3 = "Brakes:" + to_string( mover->fBrakeCtrlPos, 1, 5 ) + "+" + std::to_string( mover->LocalBrakePos ) + ( mover->SlippingWheels ? " !" : " " );
if( Global::iScreenMode[ Global::iTextMode - GLFW_KEY_F1 ] == 1 ) {
// detail mode on second key press
@@ -1324,7 +1324,7 @@ TWorld::Update_UI() {
+ ", next limit: " + std::to_string( static_cast<int>( std::floor( Controlled->Mechanik->VelNext ) ) ) + " km/h"
+ " in " + to_string( Controlled->Mechanik->ActualProximityDist * 0.001, 1 ) + " km)";
uitextline3 +=
" Pressure: " + to_string( mover->BrakePress * 100.0, 2 ) + " kPa"
" Pressure: " + to_string( mover->BrakePress * 100.0, 2 ) + " kPa"
+ " (train pipe: " + to_string( mover->PipePress * 100.0, 2 ) + " kPa)";
}
}
@@ -1342,7 +1342,7 @@ TWorld::Update_UI() {
if( tmp == nullptr ) { break; }
// if the nearest located vehicle doesn't have a direct driver, try to query its owner
auto const owner = (
tmp->Mechanik != nullptr ?
( ( tmp->Mechanik != nullptr ) && ( tmp->Mechanik->Primary() ) ) ?
tmp->Mechanik :
tmp->ctOwner );
if( owner == nullptr ){ break; }

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 17
#define VERSION_MINOR 823
#define VERSION_MINOR 825
#define VERSION_REVISION 0