mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
refactoring: obstacle detection system component separation, partial leverage of new structure
This commit is contained in:
374
Driver.cpp
374
Driver.cpp
@@ -1173,7 +1173,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
if( mvOccupied->Vel < 2.0 ) {
|
||||
// stanąć nie musi, ale zwolnić przynajmniej
|
||||
if( ( sSpeedTable[ i ].fDist < fMaxProximityDist )
|
||||
&& ( TrackBlock() > 1000.0 ) ) {
|
||||
&& ( Obstacle.distance > 1000 ) ) {
|
||||
// jest w maksymalnym zasięgu to można go pominąć (wziąć drugą prędkosć)
|
||||
// as long as there isn't any obstacle in arbitrary view range
|
||||
eSignSkip = sSpeedTable[ i ].evEvent;
|
||||
@@ -1259,7 +1259,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
|
||||
//sprawdzenie eventów pasywnych przed nami
|
||||
if( ( mvOccupied->CategoryFlag & 1 )
|
||||
&& ( sSpeedTable[ i ].fDist > pVehicles[ 0 ]->fTrackBlock - 20.0 ) ) {
|
||||
&& ( sSpeedTable[ i ].fDist > Obstacle.distance - 20 ) ) {
|
||||
// jak sygnał jest dalej niż zawalidroga
|
||||
v = 0.0; // to może być podany dla tamtego: jechać tak, jakby tam stop był
|
||||
}
|
||||
@@ -2061,7 +2061,7 @@ bool TController::CheckVehicles(TOrders user)
|
||||
&& ( p->MoverParameters->BrakeSubsystem != TBrakeSubSystem::ss_LSt ) ) {
|
||||
iDrivigFlags &= ~( moveOerlikons );
|
||||
}
|
||||
p = p->Neightbour(dir); // pojazd podłączony od wskazanej strony
|
||||
p = p->Neighbour(dir); // pojazd podłączony od wskazanej strony
|
||||
}
|
||||
if (main)
|
||||
iDrivigFlags |= movePrimary; // nie znaleziono innego, można się porządzić
|
||||
@@ -2408,11 +2408,11 @@ bool TController::PrepareEngine()
|
||||
if( !iDirection ) {
|
||||
// jeśli nie ma ustalonego kierunku
|
||||
if( ( mvControlling->PantFrontVolt != 0.0 ) || ( mvControlling->PantRearVolt != 0.0 ) || voltfront || voltrear ) {
|
||||
if( mvOccupied->Couplers[ 1 ].CouplingFlag == coupling::faux ) {
|
||||
if( mvOccupied->Couplers[ end::rear ].Connected == nullptr ) {
|
||||
// jeśli z tyłu nie ma nic
|
||||
iDirection = -1; // jazda w kierunku sprzęgu 1
|
||||
}
|
||||
if( mvOccupied->Couplers[ 0 ].CouplingFlag == coupling::faux ) {
|
||||
if( mvOccupied->Couplers[ end::front ].Connected == nullptr ) {
|
||||
// jeśli z przodu nie ma nic
|
||||
iDirection = 1; // jazda w kierunku sprzęgu 0
|
||||
}
|
||||
@@ -2618,12 +2618,12 @@ bool TController::IncBrake()
|
||||
|| ( mvOccupied->TrainType == dt_ET42 ) ) {
|
||||
// NOTE: we're doing simplified checks full of presuptions here.
|
||||
// they'll break if someone does strange thing like turning around the second unit
|
||||
if( ( mvOccupied->Couplers[ 1 ].CouplingFlag & coupling::permanent )
|
||||
&& ( mvOccupied->Couplers[ 1 ].Connected->Couplers[ 1 ].CouplingFlag > 0 ) ) {
|
||||
if( ( mvOccupied->Couplers[ end::rear ].CouplingFlag & coupling::permanent )
|
||||
&& ( mvOccupied->Couplers[ end::rear ].Connected->Couplers[ end::rear ].Connected != nullptr ) ) {
|
||||
standalone = false;
|
||||
}
|
||||
if( ( mvOccupied->Couplers[ 0 ].CouplingFlag & coupling::permanent )
|
||||
&& ( mvOccupied->Couplers[ 0 ].Connected->Couplers[ 0 ].CouplingFlag > 0 ) ) {
|
||||
if( ( mvOccupied->Couplers[ end::front ].CouplingFlag & coupling::permanent )
|
||||
&& ( mvOccupied->Couplers[ end::front ].Connected->Couplers[ end::front ].Connected != nullptr ) ) {
|
||||
standalone = false;
|
||||
}
|
||||
}
|
||||
@@ -2637,16 +2637,16 @@ bool TController::IncBrake()
|
||||
( ( mvOccupied->Couplers[ 0 ].CouplingFlag == 0 )
|
||||
&& ( mvOccupied->Couplers[ 1 ].CouplingFlag == 0 ) );
|
||||
*/
|
||||
if( pVehicles[ 0 ] != pVehicles[ 1 ] ) {
|
||||
if( pVehicles[ end::front ] != pVehicles[ end::rear ] ) {
|
||||
// more detailed version, will use manual braking also for coupled sets of controlled vehicles
|
||||
auto *vehicle = pVehicles[ 0 ]; // start from first
|
||||
auto *vehicle = pVehicles[ end::front ]; // start from first
|
||||
while( ( true == standalone )
|
||||
&& ( vehicle != nullptr ) ) {
|
||||
// NOTE: we could simplify this by doing only check of the rear coupler, but this can be quite tricky in itself
|
||||
// TODO: add easier ways to access front/rear coupler taking into account vehicle's direction
|
||||
standalone =
|
||||
( ( ( vehicle->MoverParameters->Couplers[ 0 ].CouplingFlag == 0 ) || ( vehicle->MoverParameters->Couplers[ 0 ].CouplingFlag & coupling::control ) )
|
||||
&& ( ( vehicle->MoverParameters->Couplers[ 1 ].CouplingFlag == 0 ) || ( vehicle->MoverParameters->Couplers[ 1 ].CouplingFlag & coupling::control ) ) );
|
||||
( ( ( vehicle->MoverParameters->Couplers[ end::front ].Connected == nullptr ) || ( vehicle->MoverParameters->Couplers[ end::front ].CouplingFlag & coupling::control ) )
|
||||
&& ( ( vehicle->MoverParameters->Couplers[ end::rear ].Connected == nullptr ) || ( vehicle->MoverParameters->Couplers[ end::rear ].CouplingFlag & coupling::control ) ) );
|
||||
vehicle = vehicle->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła)
|
||||
}
|
||||
}
|
||||
@@ -3625,22 +3625,21 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
|
||||
}
|
||||
WaitingTime = 0.0; // nie ma co dalej czekać, można zatrąbić i jechać, chyba że już jedzie
|
||||
}
|
||||
else // if (NewValue2==0.0) //zerowy sprzęg
|
||||
if (NewValue1 >= 0.0) // jeśli ilość wagonów inna niż wszystkie
|
||||
{ // będzie odczepianie, ale jeśli wagony są z przodu, to trzeba najpierw zmienić kierunek
|
||||
if ((mvOccupied->Couplers[mvOccupied->DirAbsolute > 0 ? 1 : 0].CouplingFlag ==
|
||||
0) ? // z tyłu nic
|
||||
(mvOccupied->Couplers[mvOccupied->DirAbsolute > 0 ? 0 : 1].CouplingFlag > 0) :
|
||||
false) // a z przodu skład
|
||||
{
|
||||
iDirectionOrder = -iDirection; // zmiana na ciągnięcie
|
||||
OrderNext(Change_direction); // najpierw zmień kierunek (zastąpi Disconnect)
|
||||
OrderPush(Disconnect); // a odczep już po zmianie kierunku
|
||||
else { // if (NewValue2==0.0) //zerowy sprzęg
|
||||
if( NewValue1 >= 0.0 ) {
|
||||
// jeśli ilość wagonów inna niż wszystkie będzie odczepianie,
|
||||
// ale jeśli wagony są z przodu, to trzeba najpierw zmienić kierunek
|
||||
if( ( mvOccupied->Couplers[ mvOccupied->DirAbsolute > 0 ? end::rear : end::front ].Connected == nullptr ) // z tyłu nic
|
||||
&& ( mvOccupied->Couplers[ mvOccupied->DirAbsolute > 0 ? end::front : end::rear ].Connected != nullptr ) ) { // a z przodu skład
|
||||
iDirectionOrder = -iDirection; // zmiana na ciągnięcie
|
||||
OrderNext( Change_direction ); // najpierw zmień kierunek (zastąpi Disconnect)
|
||||
OrderPush( Disconnect ); // a odczep już po zmianie kierunku
|
||||
}
|
||||
else if( mvOccupied->Couplers[ mvOccupied->DirAbsolute > 0 ? end::rear : end::front ].Connected != nullptr ) { // z tyłu coś
|
||||
OrderNext( Disconnect ); // jak ciągnie, to tylko odczep (NewValue1) wagonów
|
||||
}
|
||||
WaitingTime = 0.0; // nie ma co dalej czekać, można zatrąbić i jechać, chyba że już jedzie
|
||||
}
|
||||
else if (mvOccupied->Couplers[mvOccupied->DirAbsolute > 0 ? 1 : 0].CouplingFlag >
|
||||
0) // z tyłu coś
|
||||
OrderNext(Disconnect); // jak ciągnie, to tylko odczep (NewValue1) wagonów
|
||||
WaitingTime = 0.0; // nie ma co dalej czekać, można zatrąbić i jechać, chyba że już jedzie
|
||||
}
|
||||
if (NewValue1 == -1.0)
|
||||
{
|
||||
@@ -4181,55 +4180,45 @@ TController::UpdateSituation(double dt) {
|
||||
// 8. Ustalić częstotliwość świadomości AI (zatrzymanie precyzyjne - częściej, brak atrakcji
|
||||
// - rzadziej).
|
||||
|
||||
// check for potential colliders
|
||||
// check for potential collisions
|
||||
{
|
||||
auto rearvehicle = (
|
||||
pVehicles[ 0 ] == pVehicles[ 1 ] ?
|
||||
pVehicles[ 0 ] :
|
||||
pVehicles[ 1 ] );
|
||||
// HACK: vehicle order in the consist is based on intended travel direction
|
||||
// if our actual travel direction doesn't match that, we should be scanning from the other end of the consist
|
||||
auto *frontvehicle { pVehicles[ ( mvOccupied->V * iDirection >= 0 ? end::front : end::rear ) ] };
|
||||
|
||||
int routescandirection;
|
||||
// for moving vehicle determine heading from velocity; for standing fall back on the set direction
|
||||
if( ( std::abs( mvOccupied->V ) < 0.1 ? // ignore potential micro-stutters in oposite direction during "almost stop"
|
||||
if( ( std::abs( frontvehicle->MoverParameters->V ) > 0.1 ? // ignore potential micro-stutters in oposite direction during "almost stop"
|
||||
frontvehicle->MoverParameters->V > 0.0 :
|
||||
( pVehicle->DirectionGet() == frontvehicle->DirectionGet() ?
|
||||
iDirection > 0 :
|
||||
mvOccupied->V > 0.0 ) ) {
|
||||
iDirection < 0 ) ) ) {
|
||||
// towards coupler 0
|
||||
if( ( mvOccupied->V * iDirection < 0.0 )
|
||||
|| ( ( rearvehicle->NextConnected != nullptr )
|
||||
&& ( rearvehicle->MoverParameters->Couplers[ ( rearvehicle->DirectionGet() > 0 ? 1 : 0 ) ].CouplingFlag == coupling::faux ) ) ) {
|
||||
// scan behind if we're moving backward, or if we had something connected there and are moving away
|
||||
rearvehicle->ABuScanObjects( (
|
||||
pVehicle->DirectionGet() == rearvehicle->DirectionGet() ?
|
||||
-1 :
|
||||
1 ),
|
||||
fMaxProximityDist );
|
||||
}
|
||||
pVehicles[ 0 ]->ABuScanObjects( (
|
||||
pVehicle->DirectionGet() == pVehicles[ 0 ]->DirectionGet() ?
|
||||
1 :
|
||||
-1 ),
|
||||
routescanrange );
|
||||
routescandirection = end::front;
|
||||
}
|
||||
else {
|
||||
// towards coupler 1
|
||||
if( ( mvOccupied->V * iDirection < 0.0 )
|
||||
|| ( ( rearvehicle->PrevConnected != nullptr )
|
||||
&& ( rearvehicle->MoverParameters->Couplers[ ( rearvehicle->DirectionGet() > 0 ? 0 : 1 ) ].CouplingFlag == coupling::faux ) ) ) {
|
||||
// scan behind if we're moving backward, or if we had something connected there and are moving away
|
||||
rearvehicle->ABuScanObjects( (
|
||||
pVehicle->DirectionGet() == rearvehicle->DirectionGet() ?
|
||||
1 :
|
||||
-1 ),
|
||||
fMaxProximityDist );
|
||||
routescandirection = end::rear;
|
||||
}
|
||||
|
||||
Obstacle = neighbour_data();
|
||||
auto const lookup { frontvehicle->find_vehicle( routescandirection, routescanrange ) };
|
||||
|
||||
if( std::get<bool>( lookup ) == true ) {
|
||||
|
||||
Obstacle.vehicle = std::get<TDynamicObject *>( lookup );
|
||||
Obstacle.vehicle_end = std::get<int>( lookup );
|
||||
Obstacle.distance = std::get<double>( lookup );
|
||||
|
||||
if( Obstacle.distance < ( mvOccupied->CategoryFlag == 2 ? 25 : 75 ) ) {
|
||||
// at short distances (re)calculate range between couplers directly
|
||||
Obstacle.distance = TMoverParameters::CouplerDist( frontvehicle->MoverParameters, Obstacle.vehicle->MoverParameters );
|
||||
}
|
||||
pVehicles[ 0 ]->ABuScanObjects( (
|
||||
pVehicle->DirectionGet() == pVehicles[ 0 ]->DirectionGet() ?
|
||||
-1 :
|
||||
1 ),
|
||||
routescanrange );
|
||||
}
|
||||
else {
|
||||
Obstacle.distance = 10000; // legacy value. TBD, TODO: use standard -1 instead?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// tu bedzie logika sterowania
|
||||
if (AIControllFlag) {
|
||||
|
||||
@@ -4291,37 +4280,17 @@ TController::UpdateSituation(double dt) {
|
||||
if (AIControllFlag)
|
||||
{ // to robi tylko AI, wersję dla człowieka trzeba dopiero zrobić
|
||||
// sprzęgi sprawdzamy w pierwszej kolejności, bo jak połączony, to koniec
|
||||
bool ok; // true gdy się podłączy (uzyskany sprzęg będzie zgodny z żądanym)
|
||||
if (pVehicles[0]->DirectionGet() > 0) // jeśli sprzęg 0
|
||||
{ // sprzęg 0 - próba podczepienia
|
||||
if( pVehicles[ 0 ]->MoverParameters->Couplers[ 0 ].Connected ) {
|
||||
// jeśli jest coś 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);
|
||||
}
|
||||
}
|
||||
// udało się? (mogło częściowo)
|
||||
ok = (pVehicles[0]->MoverParameters->Couplers[0].CouplingFlag == iCoupler);
|
||||
}
|
||||
else // if (pVehicles[0]->MoverParameters->DirAbsolute<0) //jeśli sprzęg 1
|
||||
{ // sprzęg 1 - próba podczepienia
|
||||
if( pVehicles[ 0 ]->MoverParameters->Couplers[ 1 ].Connected ) {
|
||||
// jeśli jest coś 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);
|
||||
}
|
||||
}
|
||||
// udało się? (mogło częściowo)
|
||||
ok = (pVehicles[0]->MoverParameters->Couplers[1].CouplingFlag == iCoupler);
|
||||
}
|
||||
if (ok)
|
||||
{ // jeżeli został podłączony
|
||||
auto *vehicle { pVehicles[ end::front ] };
|
||||
auto *vehicleparameters { vehicle->MoverParameters };
|
||||
int const end { ( vehicle->DirectionGet() > 0 ? end::front : end::rear ) };
|
||||
auto const &neighbour { vehicleparameters->Neighbours[ end ] };
|
||||
// próba podczepienia
|
||||
vehicleparameters->Attach(
|
||||
end, neighbour.vehicle_end,
|
||||
neighbour.vehicle->MoverParameters,
|
||||
iCoupler );
|
||||
if( vehicleparameters->Couplers[ end ].CouplingFlag == iCoupler ) {
|
||||
// jeżeli został podłączony
|
||||
iCoupler = 0; // dalsza jazda manewrowa już bez łączenia
|
||||
iDrivigFlags &= ~moveConnect; // zdjęcie flagi doczepiania
|
||||
SetVelocity(0, 0, stopJoin); // wyłączyć przyspieszanie
|
||||
@@ -4337,7 +4306,7 @@ TController::UpdateSituation(double dt) {
|
||||
fMaxProximityDist = 5.0; //[m] w takim przedziale odległości powinien stanąć
|
||||
fVelPlus = 2.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania
|
||||
fVelMinus = 1.0; // margines prędkości powodujący załączenie napędu
|
||||
if( pVehicles[ 0 ]->fTrackBlock <= 20.0 ) {
|
||||
if( Obstacle.distance <= 20.0 ) {
|
||||
// przy zderzeniu fTrackBlock nie jest miarodajne
|
||||
// początek podczepiania, z wyłączeniem sprawdzania fTrackBlock
|
||||
iDrivigFlags |= moveConnect;
|
||||
@@ -4477,8 +4446,8 @@ TController::UpdateSituation(double dt) {
|
||||
&& ( false == TestFlag( iDrivigFlags, movePress ) )
|
||||
&& ( iCoupler == 0 )
|
||||
// && ( mvOccupied->Vel > 0.0 )
|
||||
&& ( pVehicle->MoverParameters->Couplers[ end::front ].CouplingFlag == coupling::faux )
|
||||
&& ( pVehicle->MoverParameters->Couplers[ end::rear ].CouplingFlag == coupling::faux ) ) {
|
||||
&& ( pVehicle->MoverParameters->Couplers[ end::front ].Connected == nullptr )
|
||||
&& ( pVehicle->MoverParameters->Couplers[ end::rear ].Connected == nullptr ) ) {
|
||||
SetVelocity(0, 0, stopJoin); // 1. faza odczepiania: zatrzymanie
|
||||
// WriteLog("Zatrzymanie w celu odczepienia");
|
||||
AccPreferred = std::min( 0.0, AccPreferred );
|
||||
@@ -4516,7 +4485,7 @@ TController::UpdateSituation(double dt) {
|
||||
else
|
||||
{ // samochód ma stać, aż dostanie odjazd, chyba że stoi przez kolizję
|
||||
if (eStopReason == stopBlock)
|
||||
if (pVehicles[0]->fTrackBlock > fDriverDist)
|
||||
if (Obstacle.distance > fDriverDist)
|
||||
if (AIControllFlag)
|
||||
{
|
||||
PrepareEngine(); // zmieni ustawiony kierunek
|
||||
@@ -4668,7 +4637,8 @@ TController::UpdateSituation(double dt) {
|
||||
n = 0; // nie ma co dalej sprawdzać, doczepianie zakończone
|
||||
}
|
||||
} while (n--);
|
||||
if( p ? p->MoverParameters->Couplers[ d ].CouplingFlag == coupling::faux : true ) {
|
||||
if( ( p == nullptr )
|
||||
|| ( p->MoverParameters->Couplers[ d ].Connected == nullptr ) ) {
|
||||
// no target, or already just virtual coupling
|
||||
WriteLog( mvOccupied->Name + " didn't find anything to disconnect." );
|
||||
iVehicleCount = -2; // odczepiono, co było do odczepienia
|
||||
@@ -4759,9 +4729,9 @@ TController::UpdateSituation(double dt) {
|
||||
// w trybie Connect skanować do tyłu tylko jeśli przed kolejnym sygnałem nie ma taboru do podłączenia
|
||||
// Ra 2F1H: z tym (fTrackBlock) to nie jest najlepszy pomysł, bo lepiej by
|
||||
// było porównać z odległością od sygnalizatora z przodu
|
||||
if( ( OrderList[ OrderPos ] & Connect ) ?
|
||||
( pVehicles[ 0 ]->fTrackBlock > 2000 || pVehicles[ 0 ]->fTrackBlock > FirstSemaphorDist ) :
|
||||
true ) {
|
||||
if( ( ( OrderList[ OrderPos ] & Connect ) == 0 )
|
||||
|| ( Obstacle.distance > std::min( 2000.0, FirstSemaphorDist ) ) ) {
|
||||
|
||||
if( ( comm = BackwardScan() ) != TCommandType::cm_Unknown ) {
|
||||
// jeśli w drugą można jechać
|
||||
// należy sprawdzać odległość od znalezionego sygnalizatora,
|
||||
@@ -4786,121 +4756,99 @@ TController::UpdateSituation(double dt) {
|
||||
VelDesired = fVelMax; // bo VelDesired<0 oznacza prędkość maksymalną
|
||||
|
||||
// Ra: jazda na widoczność
|
||||
/*
|
||||
// condition disabled, it'd prevent setting reduced acceleration in the last connect stage
|
||||
if ((iDrivigFlags & moveConnect) == 0) // przy końcówce podłączania nie hamować
|
||||
*/
|
||||
{ // sprawdzenie jazdy na widoczność
|
||||
auto const vehicle = pVehicles[ 0 ]; // base calculactions off relevant end of the consist
|
||||
auto const coupler =
|
||||
vehicle->MoverParameters->Couplers + (
|
||||
vehicle->DirectionGet() > 0 ?
|
||||
0 :
|
||||
1 ); // sprzęg z przodu składu
|
||||
if( ( coupler->Connected )
|
||||
&& ( coupler->CouplingFlag == coupling::faux ) ) {
|
||||
// mamy coś z przodu podłączone sprzęgiem wirtualnym
|
||||
// wyliczanie optymalnego przyspieszenia do jazdy na widoczność
|
||||
/*
|
||||
ActualProximityDist = std::min(
|
||||
if( Obstacle.distance < 5000 ) {
|
||||
// mamy coś z przodu
|
||||
// prędkość pojazdu z przodu (zakładając, że jedzie w tę samą stronę!!!)
|
||||
auto const k { Obstacle.vehicle->MoverParameters->Vel };
|
||||
if( k - vel < 5 ) {
|
||||
// porównanie modułów prędkości [km/h]
|
||||
// zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej
|
||||
ActualProximityDist = std::min<double>(
|
||||
ActualProximityDist,
|
||||
vehicle->fTrackBlock - (
|
||||
mvOccupied->CategoryFlag & 2 ?
|
||||
fMinProximityDist : // cars can bunch up tighter
|
||||
fMaxProximityDist ) ); // other vehicle types less so
|
||||
*/
|
||||
// prędkość pojazdu z przodu (zakładając, że jedzie w tę samą stronę!!!)
|
||||
double k = coupler->Connected->Vel;
|
||||
if( k - vel < 5 ) {
|
||||
// porównanie modułów prędkości [km/h]
|
||||
// zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej
|
||||
ActualProximityDist = std::min(
|
||||
ActualProximityDist,
|
||||
vehicle->fTrackBlock );
|
||||
Obstacle.distance );
|
||||
|
||||
if( ActualProximityDist <= (
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
100.0 : // cars
|
||||
250.0 ) ) { // others
|
||||
// regardless of driving mode at close distance take precaution measures:
|
||||
// match the other vehicle's speed or slow down if the other vehicle is stopped
|
||||
VelDesired =
|
||||
min_speed(
|
||||
VelDesired,
|
||||
std::max(
|
||||
k,
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
40.0 : // cars
|
||||
20.0 ) ); // others
|
||||
if( vel > VelDesired + fVelPlus ) {
|
||||
// if going too fast force some prompt braking
|
||||
AccPreferred = std::min( -0.65, AccPreferred );
|
||||
}
|
||||
if( ActualProximityDist <= (
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
100.0 : // cars
|
||||
250.0 ) ) { // others
|
||||
// regardless of driving mode at close distance take precaution measures:
|
||||
// match the other vehicle's speed or slow down if the other vehicle is stopped
|
||||
VelDesired =
|
||||
min_speed(
|
||||
VelDesired,
|
||||
std::max(
|
||||
k,
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
40.0 : // cars
|
||||
20.0 ) ); // others
|
||||
if( vel > VelDesired + fVelPlus ) {
|
||||
// if going too fast force some prompt braking
|
||||
AccPreferred = std::min( -0.65, AccPreferred );
|
||||
}
|
||||
}
|
||||
|
||||
double const distance = vehicle->fTrackBlock - fMaxProximityDist - ( fBrakeDist * 1.15 ); // odległość bezpieczna zależy od prędkości
|
||||
if( distance < 0.0 ) {
|
||||
// jeśli odległość jest zbyt mała
|
||||
if( k < 10.0 ) // k - prędkość tego z przodu
|
||||
{ // jeśli tamten porusza się z niewielką prędkością albo stoi
|
||||
if( OrderCurrentGet() & Connect ) {
|
||||
// jeśli spinanie, to jechać dalej
|
||||
AccPreferred = std::min( 0.35, AccPreferred ); // nie hamuj
|
||||
VelDesired =
|
||||
min_speed(
|
||||
VelDesired,
|
||||
( vehicle->fTrackBlock > 150.0 ?
|
||||
20.0:
|
||||
4.0 ) );
|
||||
VelNext = 2.0; // i pakuj się na tamtego
|
||||
}
|
||||
else {
|
||||
// a normalnie to hamować
|
||||
VelNext = 0.0;
|
||||
if( vehicle->fTrackBlock <= fMinProximityDist ) {
|
||||
VelDesired = 0.0;
|
||||
}
|
||||
|
||||
if( ( mvOccupied->CategoryFlag & 1 )
|
||||
&& ( OrderCurrentGet() & Obey_train ) ) {
|
||||
// trains which move normally should try to stop at safe margin
|
||||
ActualProximityDist -= fDriverDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// jeśli oba jadą, to przyhamuj lekko i ogranicz prędkość
|
||||
if( vehicle->fTrackBlock < (
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
fMaxProximityDist + 0.5 * vel : // cars
|
||||
2.0 * fMaxProximityDist + 2.0 * vel ) ) { //others
|
||||
// jak tamten jedzie wolniej a jest w drodze hamowania
|
||||
AccPreferred = std::min( -0.9, AccPreferred );
|
||||
VelNext = min_speed( std::round( k ) - 5.0, VelDesired );
|
||||
if( vehicle->fTrackBlock <= (
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
fMaxProximityDist : // cars
|
||||
2.0 * fMaxProximityDist ) ) { //others
|
||||
// try to force speed change if obstacle is really close
|
||||
VelDesired = VelNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
ReactionTime = (
|
||||
mvOccupied->Vel > 0.01 ?
|
||||
0.1 : // orientuj się, bo jest goraco
|
||||
2.0 ); // we're already standing still, so take it easy
|
||||
}
|
||||
else {
|
||||
double const distance = Obstacle.distance - fMaxProximityDist - ( fBrakeDist * 1.15 ); // odległość bezpieczna zależy od prędkości
|
||||
if( distance < 0.0 ) {
|
||||
// jeśli odległość jest zbyt mała
|
||||
if( k < 10.0 ) // k - prędkość tego z przodu
|
||||
{ // jeśli tamten porusza się z niewielką prędkością albo stoi
|
||||
if( OrderCurrentGet() & Connect ) {
|
||||
// if there's something nearby in the connect mode don't speed up too much
|
||||
// jeśli spinanie, to jechać dalej
|
||||
AccPreferred = std::min( 0.35, AccPreferred ); // nie hamuj
|
||||
VelDesired =
|
||||
min_speed(
|
||||
VelDesired,
|
||||
( vehicle->fTrackBlock > 100.0 ?
|
||||
20.0 :
|
||||
( Obstacle.distance > 150 ?
|
||||
20.0:
|
||||
4.0 ) );
|
||||
VelNext = 2.0; // i pakuj się na tamtego
|
||||
}
|
||||
else {
|
||||
// a normalnie to hamować
|
||||
VelNext = 0.0;
|
||||
if( Obstacle.distance <= fMinProximityDist ) {
|
||||
VelDesired = 0.0;
|
||||
}
|
||||
|
||||
if( ( mvOccupied->CategoryFlag & 1 )
|
||||
&& ( OrderCurrentGet() & Obey_train ) ) {
|
||||
// trains which move normally should try to stop at safe margin
|
||||
ActualProximityDist -= fDriverDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// jeśli oba jadą, to przyhamuj lekko i ogranicz prędkość
|
||||
if( Obstacle.distance < (
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
fMaxProximityDist + 0.5 * vel : // cars
|
||||
2.0 * fMaxProximityDist + 2.0 * vel ) ) { //others
|
||||
// jak tamten jedzie wolniej a jest w drodze hamowania
|
||||
AccPreferred = std::min( -0.9, AccPreferred );
|
||||
VelNext = min_speed( std::round( k ) - 5.0, VelDesired );
|
||||
if( Obstacle.distance <= (
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
fMaxProximityDist : // cars
|
||||
2.0 * fMaxProximityDist ) ) { //others
|
||||
// try to force speed change if obstacle is really close
|
||||
VelDesired = VelNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
ReactionTime = (
|
||||
mvOccupied->Vel > 0.01 ?
|
||||
0.1 : // orientuj się, bo jest goraco
|
||||
2.0 ); // we're already standing still, so take it easy
|
||||
}
|
||||
else {
|
||||
if( OrderCurrentGet() & Connect ) {
|
||||
// if there's something nearby in the connect mode don't speed up too much
|
||||
VelDesired =
|
||||
min_speed(
|
||||
VelDesired,
|
||||
( Obstacle.distance > 100 ?
|
||||
20.0 :
|
||||
4.0 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5060,7 +5008,7 @@ TController::UpdateSituation(double dt) {
|
||||
if( mvOccupied->CategoryFlag & 1 ) {
|
||||
// trains
|
||||
if( ( OrderCurrentGet() & ( Shunt | Connect ) )
|
||||
&& ( pVehicles[0]->fTrackBlock < 50.0 ) ) {
|
||||
&& ( Obstacle.distance < 50 ) ) {
|
||||
// crude detection of edge case, if approaching another vehicle coast slowly until min distance
|
||||
// this should allow to bunch up trainsets more on sidings
|
||||
VelDesired = min_speed( 5.0, VelDesired );
|
||||
@@ -6344,7 +6292,7 @@ bool TController::IsStop() const
|
||||
double
|
||||
TController::TrackBlock() const {
|
||||
|
||||
return pVehicles[ end::front ]->fTrackBlock;
|
||||
return Obstacle.distance;
|
||||
}
|
||||
|
||||
void TController::MoveTo(TDynamicObject *to)
|
||||
|
||||
1
Driver.h
1
Driver.h
@@ -376,6 +376,7 @@ private:
|
||||
std::size_t SemNextStopIndex{ std::size_t( -1 ) };
|
||||
double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki
|
||||
basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2]
|
||||
neighbour_data Obstacle; // nearest vehicle detected ahead on current route
|
||||
|
||||
// timetable
|
||||
// methods
|
||||
|
||||
848
DynObj.cpp
848
DynObj.cpp
File diff suppressed because it is too large
Load Diff
33
DynObj.h
33
DynObj.h
@@ -183,12 +183,13 @@ public:
|
||||
std::string asDestination; // dokąd pojazd ma być kierowany "(stacja):(tor)"
|
||||
Math3D::matrix4x4 mMatrix; // macierz przekształcenia do renderowania modeli
|
||||
TMoverParameters *MoverParameters; // parametry fizyki ruchu oraz przeliczanie
|
||||
TDynamicObject *NextConnected; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
|
||||
TDynamicObject *PrevConnected; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
||||
int NextConnectedNo; // numer sprzęgu podłączonego z tyłu
|
||||
int PrevConnectedNo; // numer sprzęgu podłączonego z przodu
|
||||
double fScanDist; // odległość skanowania torów na obecność innych pojazdów
|
||||
double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym pojazdem)
|
||||
inline TDynamicObject *NextConnected() { return MoverParameters->Neighbours[ end::rear ].vehicle; }; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
|
||||
inline TDynamicObject *PrevConnected() { return MoverParameters->Neighbours[ end::front ].vehicle; }; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
||||
inline TDynamicObject *NextConnected() const { return MoverParameters->Neighbours[ end::rear ].vehicle; }; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
|
||||
inline TDynamicObject *PrevConnected() const { return MoverParameters->Neighbours[ end::front ].vehicle; }; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
||||
inline int NextConnectedNo() const { return MoverParameters->Neighbours[ end::rear ].vehicle_end; }
|
||||
inline int PrevConnectedNo() const { return MoverParameters->Neighbours[ end::front ].vehicle_end; }
|
||||
// double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym pojazdem)
|
||||
|
||||
TPowerSource ConnectedEnginePowerSource( TDynamicObject const *Caller ) const;
|
||||
|
||||
@@ -455,11 +456,8 @@ private:
|
||||
int iNumAxles; // ilość osi
|
||||
std::string asModel;
|
||||
|
||||
public:
|
||||
void ABuScanObjects(int ScanDir, double ScanDist);
|
||||
|
||||
private:
|
||||
TDynamicObject *ABuFindObject( int &Foundcoupler, double &Distance, TTrack const *Track, int const Direction, int const Mycoupler );
|
||||
TDynamicObject *ABuFindObject( int &Foundcoupler, double &Distance, TTrack const *Track, int const Direction, int const Mycoupler ) const;
|
||||
void ABuCheckMyTrack();
|
||||
|
||||
public:
|
||||
@@ -470,7 +468,6 @@ private:
|
||||
TDynamicObject * Next();
|
||||
TDynamicObject * PrevC(int C);
|
||||
TDynamicObject * NextC(int C);
|
||||
double NextDistance(double d = -1.0);
|
||||
void SetdMoveLen(double dMoveLen) {
|
||||
MoverParameters->dMoveLen = dMoveLen; }
|
||||
void ResetdMoveLen() {
|
||||
@@ -485,6 +482,7 @@ private:
|
||||
return this ?
|
||||
asName :
|
||||
std::string(); };
|
||||
std::string asBaseDir;
|
||||
|
||||
// std::ofstream PneuLogFile; //zapis parametrow pneumatycznych
|
||||
// youBy - dym
|
||||
@@ -506,7 +504,6 @@ private:
|
||||
bool bDisplayCab; // czy wyswietlac kabine w train.cpp
|
||||
int iCabs; // maski bitowe modeli kabin
|
||||
TTrack *MyTrack; // McZapkie-030303: tor na ktorym stoi, ABu
|
||||
std::string asBaseDir;
|
||||
int iOverheadMask; // maska przydzielana przez AI pojazdom posiadającym pantograf, aby wymuszały jazdę bezprądową
|
||||
TTractionParam tmpTraction;
|
||||
double fAdjustment; // korekcja - docelowo przenieść do TrkFoll.cpp wraz z odległością od poprzedniego
|
||||
@@ -521,7 +518,7 @@ private:
|
||||
int init_sections( TModel3d const *Model, std::string const &Nameprefix );
|
||||
void create_controller( std::string const Type, bool const Trainset );
|
||||
void AttachPrev(TDynamicObject *Object, int iType = 1);
|
||||
bool UpdateForce(double dt, double dt1, bool FullVer);
|
||||
bool UpdateForce(double dt);
|
||||
// initiates load change by specified amounts, with a platform on specified side
|
||||
void LoadExchange( int const Disembark, int const Embark, int const Platform );
|
||||
// calculates time needed to complete current load change
|
||||
@@ -605,14 +602,13 @@ private:
|
||||
Axle1.GetTranslation() :
|
||||
Axle0.GetTranslation(); };
|
||||
// zwraca tor z aktywną osią
|
||||
inline TTrack * RaTrackGet() {
|
||||
inline TTrack * RaTrackGet() const {
|
||||
return iAxleFirst ?
|
||||
Axle1.GetTrack() :
|
||||
Axle0.GetTrack(); };
|
||||
|
||||
void couple( int const Side );
|
||||
int uncouple( int const Side );
|
||||
void CouplersDettach(double MinDist, int MyScanDir);
|
||||
void RadioStop();
|
||||
void Damage(char flag);
|
||||
void RaLightsSet(int head, int rear);
|
||||
@@ -626,8 +622,11 @@ private:
|
||||
return iDirection + iDirection - 1; };
|
||||
int DettachStatus(int dir);
|
||||
int Dettach(int dir);
|
||||
TDynamicObject * Neightbour(int &dir);
|
||||
void CoupleDist();
|
||||
TDynamicObject * Neighbour(int &dir);
|
||||
// updates potential collision sources
|
||||
void update_neighbours();
|
||||
// locates potential collision source within specified range, scanning its route in specified direction
|
||||
auto find_vehicle( int const Direction, double const Range ) const -> std::tuple<TDynamicObject *, int, double, bool>;
|
||||
TDynamicObject * ControlledFind();
|
||||
void ParamSet(int what, int into);
|
||||
// zapytanie do AI, po którym segmencie skrzyżowania jechać
|
||||
|
||||
@@ -140,7 +140,7 @@ static int const ctrain_depot = 128; //nie rozłączalny podczas zwykłyc
|
||||
// vehicle sides; exclusive
|
||||
enum end {
|
||||
front = 0,
|
||||
rear
|
||||
rear = 1
|
||||
};
|
||||
|
||||
enum side {
|
||||
@@ -609,18 +609,16 @@ struct power_coupling {
|
||||
struct TCoupling {
|
||||
/*parametry*/
|
||||
double SpringKB = 1.0; /*stala sprezystosci zderzaka/sprzegu, %tlumiennosci */
|
||||
double SpringKC = 1.0;
|
||||
double beta = 0.0;
|
||||
double DmaxB = 0.1; /*tolerancja scisku/rozciagania, sila rozerwania*/
|
||||
double FmaxB = 1000.0;
|
||||
double SpringKC = 1.0;
|
||||
double DmaxC = 0.1;
|
||||
double FmaxC = 1000.0;
|
||||
TCouplerType CouplerType = TCouplerType::NoCoupler; /*typ sprzegu*/
|
||||
/*zmienne*/
|
||||
double beta = 0.0;
|
||||
TCouplerType CouplerType = TCouplerType::NoCoupler; /*typ sprzegu*/
|
||||
int AllowedFlag = 3; //Ra: maska dostępnych
|
||||
/*zmienne*/
|
||||
int CouplingFlag = 0; /*0 - wirtualnie, 1 - sprzegi, 2 - pneumatycznie, 4 - sterowanie, 8 - kabel mocy*/
|
||||
int AllowedFlag = 3; //Ra: znaczenie jak wyżej, maska dostępnych
|
||||
bool Render = false; /*ABu: czy rysowac jak zaczepiony sprzeg*/
|
||||
double CoupleDist = 0.0; /*ABu: optymalizacja - liczenie odleglosci raz na klatkę, bez iteracji*/
|
||||
class TMoverParameters *Connected = nullptr; /*co jest podlaczone*/
|
||||
int ConnectedNr = 0; //Ra: od której strony podłączony do (Connected): 0=przód, 1=tył
|
||||
double CForce = 0.0; /*sila z jaka dzialal*/
|
||||
@@ -628,16 +626,25 @@ struct TCoupling {
|
||||
bool CheckCollision = false; /*czy sprawdzac sile czy pedy*/
|
||||
|
||||
power_coupling power_high;
|
||||
power_coupling power_low; // TODO: implement this
|
||||
// power_coupling power_low; // TODO: implement this
|
||||
|
||||
int sounds { 0 }; // sounds emitted by the coupling devices
|
||||
bool Render = false; /*ABu: czy rysowac jak zaczepiony sprzeg*/
|
||||
};
|
||||
|
||||
struct neighbour_data {
|
||||
TDynamicObject *vehicle { nullptr }; // detected obstacle
|
||||
int vehicle_end { -1 }; // facing end of the obstacle
|
||||
float distance { -1.f }; // distance to the obstacle
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TMoverParameters
|
||||
{ // Ra: wrapper na kod pascalowy, przejmujący jego funkcje Q: 20160824 - juz nie wrapper a klasa bazowa :)
|
||||
private:
|
||||
// types
|
||||
|
||||
/* TODO: implement
|
||||
// communication cable, exchanging control signals with adjacent vehicle
|
||||
struct jumper_cable {
|
||||
// types
|
||||
@@ -651,7 +658,7 @@ private:
|
||||
// integers
|
||||
// std::array<int, 1> values {};
|
||||
};
|
||||
|
||||
*/
|
||||
// basic approximation of a generic device
|
||||
// TBD: inheritance or composition?
|
||||
struct basic_device {
|
||||
@@ -818,14 +825,12 @@ private:
|
||||
public:
|
||||
|
||||
double dMoveLen = 0.0;
|
||||
std::string filename;
|
||||
/*---opis lokomotywy, wagonu itp*/
|
||||
/*--opis serii--*/
|
||||
int CategoryFlag = 1; /*1 - pociag, 2 - samochod, 4 - statek, 8 - samolot*/
|
||||
/*--sekcja stalych typowych parametrow*/
|
||||
std::string TypeName; /*nazwa serii/typu*/
|
||||
//TrainType: string; {typ: EZT/elektrowoz - Winger 040304}
|
||||
int TrainType = 0; /*Ra: powinno być szybciej niż string*/
|
||||
int TrainType = 0; /*typ: EZT/elektrowoz - Winger 040304 Ra: powinno być szybciej niż string*/
|
||||
TEngineType EngineType = TEngineType::None; /*typ napedu*/
|
||||
TPowerParameters EnginePowerSource; /*zrodlo mocy dla silnikow*/
|
||||
TPowerParameters SystemPowerSource; /*zrodlo mocy dla systemow sterowania/przetwornic/sprezarek*/
|
||||
@@ -1077,6 +1082,7 @@ public:
|
||||
TRotation Rot { 0.0, 0.0, 0.0 };
|
||||
std::string Name; /*nazwa wlasna*/
|
||||
TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami
|
||||
std::array<neighbour_data, 2> Neighbours; // potential collision sources
|
||||
bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/
|
||||
int SoundFlag = 0; /*!o patrz stale sound_ */
|
||||
double DistCounter = 0.0; /*! licznik kilometrow */
|
||||
@@ -1307,24 +1313,19 @@ public:
|
||||
double FrictConst2d= 0.0;
|
||||
double TotalMassxg = 0.0; /*TotalMass*g*/
|
||||
|
||||
Math3D::vector3 vCoulpler[2]; // powtórzenie współrzędnych sprzęgów z DynObj :/
|
||||
double fBrakeCtrlPos = -2.0; // płynna nastawa hamulca zespolonego
|
||||
bool bPantKurek3 = true; // kurek trójdrogowy (pantografu): true=połączenie z ZG, false=połączenie z małą sprężarką // domyślnie zbiornik pantografu połączony jest ze zbiornikiem głównym
|
||||
int iProblem = 0; // flagi problemów z taborem, aby AI nie musiało porównywać; 0=może jechać
|
||||
int iLights[2]; // bity zapalonych świateł tutaj, żeby dało się liczyć pobór prądu
|
||||
private:
|
||||
double CouplerDist(int Coupler);
|
||||
|
||||
public:
|
||||
TMoverParameters(double VelInitial, std::string TypeNameInit, std::string NameInit, int Cab);
|
||||
// obsługa sprzęgów
|
||||
double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
|
||||
/* double Distance(const vector3 &Loc1, const vector3 &Loc2, const vector3 &Dim1, const vector3 &Dim2);
|
||||
*/ //bool AttachA(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced = false);
|
||||
static double CouplerDist( TMoverParameters const *Left, TMoverParameters const *Right );
|
||||
static double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
|
||||
bool Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced = false, bool Audible = true);
|
||||
int DettachStatus(int ConnectNo);
|
||||
bool Dettach(int ConnectNo);
|
||||
void SetCoupleDist();
|
||||
bool DirectionForward();
|
||||
void BrakeLevelSet(double b);
|
||||
bool BrakeLevelAdd(double b);
|
||||
@@ -1340,7 +1341,7 @@ public:
|
||||
|
||||
// Q *******************************************************************************************
|
||||
double GetTrainsetVoltage(void);
|
||||
bool Physic_ReActivation(void);
|
||||
bool switch_physics(bool const State);
|
||||
double LocalBrakeRatio(void);
|
||||
double ManualBrakeRatio(void);
|
||||
double PipeRatio(void);/*ile napelniac*/
|
||||
@@ -1412,17 +1413,17 @@ public:
|
||||
/*funkcje obliczajace sily*/
|
||||
void ComputeConstans(void);//ABu: wczesniejsze wyznaczenie stalych dla liczenia sil
|
||||
double ComputeMass(void);
|
||||
void ComputeTotalForce(double dt, double dt1, bool FullVer);
|
||||
void ComputeTotalForce(double dt);
|
||||
double Adhesive(double staticfriction) const;
|
||||
double TractionForce(double dt);
|
||||
double FrictionForce(double R, int TDamage);
|
||||
double BrakeForceR(double ratio, double velocity);
|
||||
double BrakeForceP(double press, double velocity);
|
||||
double BrakeForce(const TTrackParam &Track);
|
||||
double CouplerForce(int CouplerN, double dt);
|
||||
double CouplerForce(int const End, double dt);
|
||||
void CollisionDetect(int CouplerN, double dt);
|
||||
/*obrot kol uwzgledniajacy poslizg*/
|
||||
double ComputeRotatingWheel(double WForce, double dt, double n);
|
||||
double ComputeRotatingWheel(double WForce, double dt, double n) const;
|
||||
|
||||
/*--funkcje dla lokomotyw*/
|
||||
bool DirectionBackward(void);/*! kierunek ruchu*/
|
||||
|
||||
@@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "stdafx.h"
|
||||
#include "MOVER.h"
|
||||
|
||||
#include "DynObj.h"
|
||||
#include "Oerlikon_ESt.h"
|
||||
#include "utilities.h"
|
||||
#include "Globals.h"
|
||||
@@ -383,168 +384,118 @@ double TMoverParameters::Distance(const TLocation &Loc1, const TLocation &Loc2,
|
||||
{ // zwraca odległość pomiędzy pojazdami (Loc1) i (Loc2) z uwzględnieneim ich długości (kule!)
|
||||
return hypot(Loc2.X - Loc1.X, Loc1.Y - Loc2.Y) - 0.5 * (Dim2.L + Dim1.L);
|
||||
};
|
||||
/*
|
||||
double TMoverParameters::Distance(const vector3 &s1, const vector3 &s2, const vector3 &d1,
|
||||
const vector3 &d2){
|
||||
// obliczenie odległości prostopadłościanów o środkach (s1) i (s2) i wymiarach (d1) i (d2)
|
||||
// return 0.0; //będzie zgłaszać warning - funkcja do usunięcia, chyba że się przyda...
|
||||
};
|
||||
*/
|
||||
double TMoverParameters::CouplerDist(int Coupler)
|
||||
{ // obliczenie odległości pomiędzy sprzęgami (kula!)
|
||||
Couplers[Coupler].CoupleDist =
|
||||
Distance(
|
||||
Loc, Couplers[Coupler].Connected->Loc,
|
||||
Dim, Couplers[Coupler].Connected->Dim); // odległość pomiędzy sprzęgami (kula!)
|
||||
|
||||
return Couplers[ Coupler ].CoupleDist;
|
||||
double TMoverParameters::CouplerDist(TMoverParameters const *Left, TMoverParameters const *Right)
|
||||
{ // obliczenie odległości pomiędzy sprzęgami (kula!)
|
||||
return
|
||||
Distance(
|
||||
Left->Loc, Right->Loc,
|
||||
Left->Dim, Right->Dim); // odległość pomiędzy sprzęgami (kula!)
|
||||
};
|
||||
|
||||
bool TMoverParameters::Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced, bool Audible)
|
||||
{ //łączenie do swojego sprzęgu (ConnectNo) pojazdu (ConnectTo) stroną (ConnectToNr)
|
||||
// Ra: zwykle wykonywane dwukrotnie, dla każdego pojazdu oddzielnie
|
||||
// Ra: trzeba by odróżnić wymóg dociśnięcia od uszkodzenia sprzęgu przy podczepianiu AI do
|
||||
// składu
|
||||
if (ConnectTo) // jeśli nie pusty
|
||||
{
|
||||
auto &coupler = Couplers[ ConnectNo ];
|
||||
if (ConnectToNr != 2)
|
||||
coupler.ConnectedNr = ConnectToNr; // 2=nic nie podłączone
|
||||
coupler.Connected = ConnectTo; // tak podpiąć (do siebie) zawsze można, najwyżej będzie wirtualny
|
||||
CouplerDist( ConnectNo ); // przeliczenie odległości pomiędzy sprzęgami
|
||||
// Ra: trzeba by odróżnić wymóg dociśnięcia od uszkodzenia sprzęgu przy podczepianiu AI do składu
|
||||
|
||||
if (CouplingType == coupling::faux)
|
||||
return false; // wirtualny więcej nic nie robi
|
||||
|
||||
auto &othercoupler = ConnectTo->Couplers[ coupler.ConnectedNr ];
|
||||
if( ( Forced )
|
||||
|| ( ( coupler.CoupleDist <= dEpsilon )
|
||||
&& ( coupler.CouplerType != TCouplerType::NoCoupler )
|
||||
&& ( coupler.CouplerType == othercoupler.CouplerType ) ) )
|
||||
{ // stykaja sie zderzaki i kompatybilne typy sprzegow, chyba że łączenie na starcie
|
||||
if( coupler.CouplingFlag == ctrain_virtual ) {
|
||||
// jeśli wcześniej nie było połączone, ustalenie z której strony rysować sprzęg
|
||||
coupler.Render = true; // tego rysować
|
||||
othercoupler.Render = false; // a tego nie
|
||||
};
|
||||
auto const couplingchange { CouplingType ^ coupler.CouplingFlag };
|
||||
coupler.CouplingFlag = CouplingType; // ustawienie typu sprzęgu
|
||||
// if (CouplingType!=ctrain_virtual) //Ra: wirtualnego nie łączymy zwrotnie!
|
||||
//{//jeśli łączenie sprzęgiem niewirtualnym, ustawiamy połączenie zwrotne
|
||||
othercoupler.CouplingFlag = CouplingType;
|
||||
othercoupler.Connected = this;
|
||||
othercoupler.CoupleDist = coupler.CoupleDist;
|
||||
|
||||
if( ( true == Audible ) && ( couplingchange != 0 ) ) {
|
||||
// set sound event flag
|
||||
int soundflag{ sound::none };
|
||||
std::vector<std::pair<coupling, sound>> const soundmappings = {
|
||||
{ coupling::coupler, sound::attachcoupler },
|
||||
{ coupling::brakehose, sound::attachbrakehose },
|
||||
{ coupling::mainhose, sound::attachmainhose },
|
||||
{ coupling::control, sound::attachcontrol},
|
||||
{ coupling::gangway, sound::attachgangway},
|
||||
{ coupling::heating, sound::attachheating} };
|
||||
for( auto const &soundmapping : soundmappings ) {
|
||||
if( ( couplingchange & soundmapping.first ) != 0 ) {
|
||||
soundflag |= soundmapping.second;
|
||||
}
|
||||
}
|
||||
SetFlag( coupler.sounds, soundflag );
|
||||
}
|
||||
|
||||
return true;
|
||||
//}
|
||||
// podłączenie nie udało się - jest wirtualne
|
||||
}
|
||||
if( ( ConnectTo == nullptr )
|
||||
|| ( CouplingType == coupling::faux ) ) {
|
||||
return false;
|
||||
}
|
||||
return false; // brak podłączanego pojazdu, zbyt duża odległość, niezgodny typ sprzęgu, brak
|
||||
// sprzęgu, brak haka
|
||||
};
|
||||
|
||||
auto &coupler { Couplers[ ConnectNo ] };
|
||||
auto &othercoupler = ConnectTo->Couplers[ ( ConnectToNr != 2 ? ConnectToNr : coupler.ConnectedNr ) ];
|
||||
auto const distance { CouplerDist( this, ConnectTo ) };
|
||||
|
||||
// to jest już niepotrzebne bo nie ma Delphi
|
||||
//bool TMoverParameters::Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo,
|
||||
// int CouplingType, bool Forced)
|
||||
//{ //łączenie do (ConnectNo) pojazdu (ConnectTo) stroną (ConnectToNr)
|
||||
// return Attach(ConnectNo, ConnectToNr, (TMoverParameters *)ConnectTo, CouplingType, Forced);
|
||||
//};
|
||||
auto const couplercheck {
|
||||
( Forced )
|
||||
|| ( ( distance <= dEpsilon )
|
||||
&& ( coupler.CouplerType != TCouplerType::NoCoupler )
|
||||
&& ( coupler.CouplerType == othercoupler.CouplerType ) ) };
|
||||
|
||||
if( false == couplercheck ) { return false; }
|
||||
|
||||
// stykaja sie zderzaki i kompatybilne typy sprzegow, chyba że łączenie na starcie
|
||||
if( coupler.CouplingFlag == coupling::faux ) {
|
||||
// jeśli wcześniej nie było połączone, ustalenie z której strony rysować sprzęg
|
||||
coupler.Render = true; // tego rysować
|
||||
othercoupler.Render = false; // a tego nie
|
||||
};
|
||||
auto const couplingchange { CouplingType ^ coupler.CouplingFlag };
|
||||
coupler.Connected = ConnectTo;
|
||||
coupler.CouplingFlag = CouplingType; // ustawienie typu sprzęgu
|
||||
if( ConnectToNr != 2 ) {
|
||||
coupler.ConnectedNr = ConnectToNr; // 2=nic nie podłączone
|
||||
}
|
||||
othercoupler.Connected = this;
|
||||
othercoupler.CouplingFlag = CouplingType;
|
||||
othercoupler.ConnectedNr = ConnectNo;
|
||||
|
||||
if( ( true == Audible ) && ( couplingchange != 0 ) ) {
|
||||
// set sound event flag
|
||||
int soundflag{ sound::none };
|
||||
std::vector<std::pair<coupling, sound>> const soundmappings = {
|
||||
{ coupling::coupler, sound::attachcoupler },
|
||||
{ coupling::brakehose, sound::attachbrakehose },
|
||||
{ coupling::mainhose, sound::attachmainhose },
|
||||
{ coupling::control, sound::attachcontrol},
|
||||
{ coupling::gangway, sound::attachgangway},
|
||||
{ coupling::heating, sound::attachheating} };
|
||||
for( auto const &soundmapping : soundmappings ) {
|
||||
if( ( couplingchange & soundmapping.first ) != 0 ) {
|
||||
soundflag |= soundmapping.second;
|
||||
}
|
||||
}
|
||||
SetFlag( coupler.sounds, soundflag );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int TMoverParameters::DettachStatus(int ConnectNo)
|
||||
{ // Ra: sprawdzenie, czy odległość jest dobra do rozłączania
|
||||
// powinny być 3 informacje: =0 sprzęg już rozłączony, <0 da się rozłączyć. >0 nie da się
|
||||
// rozłączyć
|
||||
// powinny być 3 informacje: =0 sprzęg już rozłączony, <0 da się rozłączyć. >0 nie da się rozłączyć
|
||||
if (!Couplers[ConnectNo].Connected)
|
||||
return 0; // nie ma nic, to rozłączanie jest OK
|
||||
if ((Couplers[ConnectNo].CouplingFlag & ctrain_coupler) == 0)
|
||||
return -Couplers[ConnectNo].CouplingFlag; // hak nie połączony - rozłączanie jest OK
|
||||
if (TestFlag(DamageFlag, dtrain_coupling))
|
||||
return -Couplers[ConnectNo].CouplingFlag; // hak urwany - rozłączanie jest OK
|
||||
// ABu021104: zakomentowane 'and (CouplerType<>Articulated)' w warunku, nie wiem co to bylo, ale
|
||||
// za to teraz dziala odczepianie... :) }
|
||||
// if (CouplerType==Articulated) return false; //sprzęg nie do rozpięcia - może być tylko urwany
|
||||
// Couplers[ConnectNo].CoupleDist=Distance(Loc,Couplers[ConnectNo].Connected->Loc,Dim,Couplers[ConnectNo].Connected->Dim);
|
||||
CouplerDist(ConnectNo);
|
||||
if (Couplers[ConnectNo].CouplerType == TCouplerType::Screw ? Couplers[ConnectNo].CoupleDist < 0.01 : true)
|
||||
// CouplerDist(ConnectNo);
|
||||
if (Couplers[ConnectNo].CouplerType == TCouplerType::Screw ? Neighbours[ConnectNo].distance < 0.01 : true)
|
||||
return -Couplers[ConnectNo].CouplingFlag; // można rozłączać, jeśli dociśnięty
|
||||
return (Couplers[ConnectNo].CoupleDist > 0.2) ? -Couplers[ConnectNo].CouplingFlag :
|
||||
return (Neighbours[ConnectNo].distance > 0.2) ? -Couplers[ConnectNo].CouplingFlag :
|
||||
Couplers[ConnectNo].CouplingFlag;
|
||||
};
|
||||
|
||||
bool TMoverParameters::Dettach(int ConnectNo)
|
||||
{ // rozlaczanie
|
||||
if (!Couplers[ConnectNo].Connected)
|
||||
return true; // nie ma nic, to odczepiono
|
||||
// with Couplers[ConnectNo] do
|
||||
int i = DettachStatus(ConnectNo); // stan sprzęgu
|
||||
if (i < 0)
|
||||
{ // gdy scisniete zderzaki, chyba ze zerwany sprzeg (wirtualnego nie odpinamy z drugiej strony)
|
||||
// Couplers[ConnectNo].Connected=NULL; //lepiej zostawic bo przeciez trzeba kontrolowac
|
||||
// zderzenia odczepionych
|
||||
Couplers[ConnectNo].Connected->Couplers[Couplers[ConnectNo].ConnectedNr].CouplingFlag =
|
||||
0; // pozostaje sprzęg wirtualny
|
||||
Couplers[ConnectNo].CouplingFlag = 0; // pozostaje sprzęg wirtualny
|
||||
|
||||
auto &coupler { Couplers[ ConnectNo ] };
|
||||
auto &othervehicle { coupler.Connected };
|
||||
auto &othercoupler { othervehicle->Couplers[ coupler.ConnectedNr ] };
|
||||
|
||||
if( othervehicle == nullptr ) { return true; } // nie ma nic, to odczepiono
|
||||
|
||||
auto const i = DettachStatus(ConnectNo); // stan sprzęgu
|
||||
if (i < 0) {
|
||||
// gdy scisniete zderzaki, chyba ze zerwany sprzeg (wirtualnego nie odpinamy z drugiej strony)
|
||||
std::tie( coupler.Connected, coupler.ConnectedNr, coupler.CouplingFlag )
|
||||
= std::tie( othercoupler.Connected, othercoupler.ConnectedNr, othercoupler.CouplingFlag )
|
||||
= std::make_tuple( nullptr, -1, coupling::faux );
|
||||
// set sound event flag
|
||||
SetFlag( Couplers[ ConnectNo ].sounds, sound::detachall );
|
||||
SetFlag( coupler.sounds, sound::detachall );
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (i > 0)
|
||||
{ // odłączamy węże i resztę, pozostaje sprzęg fizyczny, który wymaga dociśnięcia (z wirtualnym
|
||||
// nic)
|
||||
Couplers[ConnectNo].CouplingFlag &= ctrain_coupler;
|
||||
Couplers[ConnectNo].Connected->Couplers[Couplers[ConnectNo].ConnectedNr].CouplingFlag =
|
||||
Couplers[ConnectNo].CouplingFlag;
|
||||
{ // odłączamy węże i resztę, pozostaje sprzęg fizyczny, który wymaga dociśnięcia (z wirtualnym nic)
|
||||
coupler.CouplingFlag &= coupling::coupler;
|
||||
othercoupler.CouplingFlag &= coupling::coupler;
|
||||
}
|
||||
return false; // jeszcze nie rozłączony
|
||||
};
|
||||
|
||||
// przeliczenie odległości sprzęgów
|
||||
void TMoverParameters::SetCoupleDist() {
|
||||
/*
|
||||
double const MaxDist = 100.0; // 2x average max proximity distance. TODO: rearrange ito something more elegant
|
||||
*/
|
||||
for( int coupleridx = 0; coupleridx <= 1; ++coupleridx ) {
|
||||
|
||||
if( Couplers[ coupleridx ].Connected == nullptr ) { continue; }
|
||||
|
||||
CouplerDist( coupleridx );
|
||||
if( CategoryFlag & 2 ) {
|
||||
// Ra: dla samochodów zderzanie kul to za mało
|
||||
// NOTE: whatever calculation was supposed to be here, ain't
|
||||
}
|
||||
/*
|
||||
if( ( Couplers[ coupleridx ].CouplingFlag == coupling::faux )
|
||||
&& ( Couplers[ coupleridx ].CoupleDist > MaxDist ) ) {
|
||||
// zerwij kontrolnie wirtualny sprzeg
|
||||
// Connected.Couplers[CNext].Connected:=nil; //Ra: ten podłączony niekoniecznie jest wirtualny
|
||||
Couplers[ coupleridx ].Connected = nullptr;
|
||||
Couplers[ coupleridx ].ConnectedNr = 2;
|
||||
}
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
bool TMoverParameters::DirectionForward()
|
||||
{
|
||||
if ((MainCtrlPosNo > 0) && (ActiveDir < 1) && (MainCtrlPos == 0))
|
||||
@@ -1064,7 +1015,8 @@ void TMoverParameters::CollisionDetect(int CouplerN, double dt)
|
||||
CCF =
|
||||
ComputeCollision(
|
||||
coupler.Connected->V,
|
||||
V, coupler.Connected->TotalMass,
|
||||
V,
|
||||
coupler.Connected->TotalMass,
|
||||
TotalMass,
|
||||
(coupler.beta + coupler.Connected->Couplers[coupler.ConnectedNr].beta) / 2.0,
|
||||
VirtualCoupling)
|
||||
@@ -3755,7 +3707,7 @@ void TMoverParameters::UpdateScndPipePressure(double dt)
|
||||
c = Couplers[0].Connected; // skrot
|
||||
dv1 = 0.5 * dt * PF(ScndPipePress, c->ScndPipePress, Spz * 0.75);
|
||||
if (dv1 * dv1 > 0.00000000000001)
|
||||
c->Physic_ReActivation();
|
||||
c->switch_physics( true );
|
||||
c->Pipe2->Flow(-dv1);
|
||||
}
|
||||
// sprzeg 2
|
||||
@@ -3765,7 +3717,7 @@ void TMoverParameters::UpdateScndPipePressure(double dt)
|
||||
c = Couplers[1].Connected; // skrot
|
||||
dv2 = 0.5 * dt * PF(ScndPipePress, c->ScndPipePress, Spz * 0.75);
|
||||
if (dv2 * dv2 > 0.00000000000001)
|
||||
c->Physic_ReActivation();
|
||||
c->switch_physics( true );
|
||||
c->Pipe2->Flow(-dv2);
|
||||
}
|
||||
if ((Couplers[1].Connected != NULL) && (Couplers[0].Connected != NULL))
|
||||
@@ -3816,7 +3768,7 @@ double TMoverParameters::GetDVc(double dt)
|
||||
c = Couplers[0].Connected; // skrot //0.08 //e/D * L/D = e/D^2 * L
|
||||
dv1 = 0.5 * dt * PF(PipePress, c->PipePress, (Spg) / (1.0 + 0.015 / Spg * Dim.L));
|
||||
if (dv1 * dv1 > 0.00000000000001)
|
||||
c->Physic_ReActivation();
|
||||
c->switch_physics( true );
|
||||
c->Pipe->Flow(-dv1);
|
||||
}
|
||||
// sprzeg 2
|
||||
@@ -3826,7 +3778,7 @@ double TMoverParameters::GetDVc(double dt)
|
||||
c = Couplers[1].Connected; // skrot
|
||||
dv2 = 0.5 * dt * PF(PipePress, c->PipePress, (Spg) / (1.0 + 0.015 / Spg * Dim.L));
|
||||
if (dv2 * dv2 > 0.00000000000001)
|
||||
c->Physic_ReActivation();
|
||||
c->switch_physics( true );
|
||||
c->Pipe->Flow(-dv2);
|
||||
}
|
||||
//if ((Couplers[1].Connected != NULL) && (Couplers[0].Connected != NULL))
|
||||
@@ -3922,143 +3874,138 @@ double TMoverParameters::ComputeMass(void)
|
||||
// Q: 20160713
|
||||
// Obliczanie wypadkowej siły z wszystkich działających sił
|
||||
// *************************************************************************************************
|
||||
void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer)
|
||||
{
|
||||
int b;
|
||||
double Fwheels = 0.0;
|
||||
// TBD, TODO: move some of the calculations out of the method, they're relevant to more than just force calculations
|
||||
void TMoverParameters::ComputeTotalForce(double dt) {
|
||||
|
||||
if (PhysicActivation)
|
||||
{
|
||||
// EventFlag:=false; {jesli cos sie zlego
|
||||
// wydarzy to ustawiane na true}
|
||||
// SoundFlag:=0; {jesli ma byc jakis dzwiek
|
||||
// to zapalany jet odpowiedni bit}
|
||||
// to powinno byc zerowane na zewnatrz
|
||||
|
||||
// juz zoptymalizowane:
|
||||
FStand = FrictionForce(RunningShape.R, RunningTrack.DamageFlag); // siła oporów ruchu
|
||||
Vel = abs(V) * 3.6; // prędkość w km/h
|
||||
nrot = v2n(); // przeliczenie prędkości liniowej na obrotową
|
||||
|
||||
if( (true == TestFlag(BrakeMethod, bp_MHS))
|
||||
&& (PipePress < 3.0)
|
||||
&& (Vel > 45)
|
||||
&& (true == TestFlag(BrakeDelayFlag, bdelay_M))) // ustawione na sztywno na 3 bar
|
||||
FStand += TrackBrakeForce; // doliczenie hamowania hamulcem szynowym
|
||||
// w charakterystykach jest wartość siły hamowania zamiast nacisku
|
||||
// if(FullVer=true) then
|
||||
// ABu: to dla optymalizacji, bo chyba te rzeczy wystarczy sprawdzac 1 raz na
|
||||
// klatke?
|
||||
LastSwitchingTime += dt1;
|
||||
if (EngineType == TEngineType::ElectricSeriesMotor)
|
||||
LastRelayTime += dt1;
|
||||
if( Mains && /*(abs(CabNo) < 2) &&*/ ( EngineType == TEngineType::ElectricSeriesMotor ) ) // potem ulepszyc! pantogtrafy!
|
||||
{ // Ra 2014-03: uwzględnienie kierunku jazdy w napięciu na silnikach, a powinien być
|
||||
// zdefiniowany nawrotnik
|
||||
if( CabNo == 0 )
|
||||
Voltage = RunningTraction.TractionVoltage * ActiveDir;
|
||||
else
|
||||
Voltage = RunningTraction.TractionVoltage * DirAbsolute; // ActiveDir*CabNo;
|
||||
} // bo nie dzialalo
|
||||
else if( ( EngineType == TEngineType::ElectricInductionMotor )
|
||||
|| ( ( ( Couplers[ end::front ].CouplingFlag & ctrain_power ) == ctrain_power )
|
||||
|| ( ( Couplers[ end::rear ].CouplingFlag & ctrain_power ) == ctrain_power ) ) ) {
|
||||
// potem ulepszyc! pantogtrafy!
|
||||
Voltage =
|
||||
std::max(
|
||||
RunningTraction.TractionVoltage,
|
||||
std::max(
|
||||
Couplers[ end::front ].power_high.voltage,
|
||||
Couplers[ end::rear ].power_high.voltage ) );
|
||||
}
|
||||
else {
|
||||
Voltage = 0;
|
||||
}
|
||||
|
||||
if (Power > 0)
|
||||
FTrain = TractionForce(dt);
|
||||
else
|
||||
FTrain = 0;
|
||||
|
||||
Fb = BrakeForce(RunningTrack);
|
||||
Fwheels = FTrain - Fb * Sign(V);
|
||||
if( ( Vel > 0.001 ) // crude trap, to prevent braked stationary vehicles from passing fb > mass * adhesive test
|
||||
&& ( std::abs(Fwheels) > TotalMassxg * Adhesive( RunningTrack.friction ) ) ) // poslizg
|
||||
{
|
||||
SlippingWheels = true;
|
||||
}
|
||||
if( true == SlippingWheels ) {
|
||||
// TrainForce:=TrainForce-Fb;
|
||||
double temp_nrot = ComputeRotatingWheel(Fwheels -
|
||||
Sign(nrot * M_PI * WheelDiameter - V) *
|
||||
Adhesive(RunningTrack.friction) * TotalMassxg,
|
||||
dt, nrot);
|
||||
Fwheels = Sign(temp_nrot * M_PI * WheelDiameter - V) * TotalMassxg * Adhesive(RunningTrack.friction);
|
||||
if (Fwheels*Sign(V)>0)
|
||||
{
|
||||
FTrain = Fwheels + Fb*Sign(V);
|
||||
}
|
||||
else if (FTrain*Sign(V)>0)
|
||||
{
|
||||
Fb = FTrain*Sign(V) - Fwheels*Sign(V);
|
||||
}
|
||||
else
|
||||
{
|
||||
Fb = -Fwheels*Sign(V);
|
||||
FTrain = 0;
|
||||
}
|
||||
if (nrot < 0.1)
|
||||
{
|
||||
WheelFlat = sqrt(square(WheelFlat) + abs(Fwheels) / NAxles*Vel*0.000002);
|
||||
}
|
||||
if (Sign(nrot * M_PI * WheelDiameter - V)*Sign(temp_nrot * M_PI * WheelDiameter - V) < 0)
|
||||
{
|
||||
SlippingWheels = false;
|
||||
temp_nrot = V / M_PI / WheelDiameter;
|
||||
}
|
||||
|
||||
|
||||
nrot = temp_nrot;
|
||||
}
|
||||
// else SlippingWheels:=false;
|
||||
// FStand:=0;
|
||||
for (b = 0; b < 2; ++b)
|
||||
if (Couplers[b].Connected != NULL) /*and (Couplers[b].CouplerType<>Bare) and
|
||||
(Couplers[b].CouplerType<>Articulated)*/
|
||||
{ // doliczenie sił z innych pojazdów
|
||||
Couplers[b].CForce = CouplerForce(b, dt);
|
||||
FTrain += Couplers[b].CForce;
|
||||
}
|
||||
else
|
||||
Couplers[b].CForce = 0;
|
||||
// FStand:=Fb+FrictionForce(RunningShape.R,RunningTrack.DamageFlag);
|
||||
FStand += Fb;
|
||||
FTrain +=
|
||||
TotalMassxg * RunningShape.dHtrack; // doliczenie składowej stycznej grawitacji
|
||||
//!niejawne przypisanie zmiennej!
|
||||
FTotal = FTrain - Sign(V) * FStand;
|
||||
}
|
||||
Vel = std::abs(V) * 3.6; // prędkość w km/h
|
||||
|
||||
// McZapkie-031103: sprawdzanie czy warto liczyc fizyke i inne updaty
|
||||
// ABu 300105: cos tu mieszalem , dziala teraz troche lepiej, wiec zostawiam
|
||||
if ((CabNo == 0) && (Vel < 0.0001) && (abs(AccS) < 0.0001) && (TrainType != dt_EZT))
|
||||
{
|
||||
if (!PhysicActivation)
|
||||
{
|
||||
if (Couplers[0].Connected != NULL)
|
||||
if ((Couplers[0].Connected->Vel > 0.0001) ||
|
||||
(abs(Couplers[0].Connected->AccS) > 0.0001))
|
||||
Physic_ReActivation();
|
||||
if (Couplers[1].Connected != NULL)
|
||||
if ((Couplers[1].Connected->Vel > 0.0001) ||
|
||||
(abs(Couplers[1].Connected->AccS) > 0.0001))
|
||||
Physic_ReActivation();
|
||||
}
|
||||
if (LastSwitchingTime > 5) // 10+Random(100) then
|
||||
PhysicActivation = false; // zeby nie brac pod uwage braku V po uruchomieniu programu
|
||||
auto const vehicleisactive {
|
||||
( CabNo != 0 )
|
||||
|| ( Vel > 0.0001 )
|
||||
|| ( std::abs( AccS ) > 0.0001 )
|
||||
|| ( LastSwitchingTime < 5 )
|
||||
|| ( TrainType == dt_EZT )
|
||||
|| ( TrainType == dt_DMU ) };
|
||||
|
||||
auto const movingvehicleahead {
|
||||
( Neighbours[ end::front ].vehicle != nullptr )
|
||||
&& ( ( Neighbours[ end::front ].vehicle->MoverParameters->Vel > 0.0001 )
|
||||
|| ( std::abs( Neighbours[ end::front ].vehicle->MoverParameters->AccS ) > 0.0001 ) ) };
|
||||
|
||||
auto const movingvehiclebehind {
|
||||
( Neighbours[ end::rear ].vehicle != nullptr )
|
||||
&& ( ( Neighbours[ end::rear ].vehicle->MoverParameters->Vel > 0.0001 )
|
||||
|| ( std::abs( Neighbours[ end::rear ].vehicle->MoverParameters->AccS ) > 0.0001 ) ) };
|
||||
|
||||
auto const calculatephysics { vehicleisactive || movingvehicleahead || movingvehiclebehind };
|
||||
|
||||
switch_physics( calculatephysics );
|
||||
}
|
||||
else
|
||||
PhysicActivation = true;
|
||||
|
||||
if( false == PhysicActivation ) { return; }
|
||||
|
||||
// juz zoptymalizowane:
|
||||
FStand = FrictionForce(RunningShape.R, RunningTrack.DamageFlag); // siła oporów ruchu
|
||||
nrot = v2n(); // przeliczenie prędkości liniowej na obrotową
|
||||
|
||||
if( ( true == TestFlag( BrakeMethod, bp_MHS ) )
|
||||
&& ( PipePress < 3.0 ) // ustawione na sztywno na 3 bar
|
||||
&& ( Vel > 45 )
|
||||
&& ( true == TestFlag( BrakeDelayFlag, bdelay_M ) ) ) {
|
||||
// doliczenie hamowania hamulcem szynowym
|
||||
FStand += TrackBrakeForce;
|
||||
}
|
||||
// w charakterystykach jest wartość siły hamowania zamiast nacisku
|
||||
|
||||
LastSwitchingTime += dt;
|
||||
if( EngineType == TEngineType::ElectricSeriesMotor ) {
|
||||
LastRelayTime += dt;
|
||||
}
|
||||
if( Mains && /*(abs(CabNo) < 2) &&*/ ( EngineType == TEngineType::ElectricSeriesMotor ) ) // potem ulepszyc! pantogtrafy!
|
||||
{ // Ra 2014-03: uwzględnienie kierunku jazdy w napięciu na silnikach, a powinien być zdefiniowany nawrotnik
|
||||
if( CabNo == 0 )
|
||||
Voltage = RunningTraction.TractionVoltage * ActiveDir;
|
||||
else
|
||||
Voltage = RunningTraction.TractionVoltage * DirAbsolute; // ActiveDir*CabNo;
|
||||
} // bo nie dzialalo
|
||||
else if( ( EngineType == TEngineType::ElectricInductionMotor )
|
||||
|| ( ( ( Couplers[ end::front ].CouplingFlag & ctrain_power ) == ctrain_power )
|
||||
|| ( ( Couplers[ end::rear ].CouplingFlag & ctrain_power ) == ctrain_power ) ) ) {
|
||||
// potem ulepszyc! pantogtrafy!
|
||||
Voltage =
|
||||
std::max(
|
||||
RunningTraction.TractionVoltage,
|
||||
std::max(
|
||||
Couplers[ end::front ].power_high.voltage,
|
||||
Couplers[ end::rear ].power_high.voltage ) );
|
||||
}
|
||||
else {
|
||||
Voltage = 0;
|
||||
}
|
||||
|
||||
FTrain = (
|
||||
Power > 0 ?
|
||||
TractionForce( dt ) :
|
||||
0 );
|
||||
|
||||
Fb = BrakeForce(RunningTrack);
|
||||
// poslizg
|
||||
auto Fwheels { FTrain - Fb * Sign( V ) };
|
||||
if( ( Vel > 0.001 ) // crude trap, to prevent braked stationary vehicles from passing fb > mass * adhesive test
|
||||
&& ( std::abs(Fwheels) > TotalMassxg * Adhesive( RunningTrack.friction ) ) ) {
|
||||
SlippingWheels = true;
|
||||
}
|
||||
if( true == SlippingWheels ) {
|
||||
|
||||
double temp_nrot = ComputeRotatingWheel(Fwheels -
|
||||
Sign(nrot * M_PI * WheelDiameter - V) *
|
||||
Adhesive(RunningTrack.friction) * TotalMassxg,
|
||||
dt, nrot);
|
||||
Fwheels = Sign(temp_nrot * M_PI * WheelDiameter - V) * TotalMassxg * Adhesive(RunningTrack.friction);
|
||||
if (Fwheels*Sign(V)>0)
|
||||
{
|
||||
FTrain = Fwheels + Fb*Sign(V);
|
||||
}
|
||||
else if (FTrain*Sign(V)>0)
|
||||
{
|
||||
Fb = FTrain*Sign(V) - Fwheels*Sign(V);
|
||||
}
|
||||
else
|
||||
{
|
||||
Fb = -Fwheels*Sign(V);
|
||||
FTrain = 0;
|
||||
}
|
||||
if (nrot < 0.1)
|
||||
{
|
||||
WheelFlat = sqrt(square(WheelFlat) + abs(Fwheels) / NAxles*Vel*0.000002);
|
||||
}
|
||||
if (Sign(nrot * M_PI * WheelDiameter - V)*Sign(temp_nrot * M_PI * WheelDiameter - V) < 0)
|
||||
{
|
||||
SlippingWheels = false;
|
||||
temp_nrot = V / M_PI / WheelDiameter;
|
||||
}
|
||||
|
||||
|
||||
nrot = temp_nrot;
|
||||
}
|
||||
// doliczenie sił z innych pojazdów
|
||||
for( int end = end::front; end <= end::rear; ++end ) {
|
||||
if( Neighbours[ end ].vehicle != nullptr ) {
|
||||
Couplers[ end ].CForce = CouplerForce( end, dt );
|
||||
FTrain += Couplers[ end ].CForce;
|
||||
}
|
||||
else
|
||||
Couplers[ end ].CForce = 0;
|
||||
}
|
||||
|
||||
FStand += Fb;
|
||||
// doliczenie składowej stycznej grawitacji
|
||||
FTrain += TotalMassxg * RunningShape.dHtrack;
|
||||
//!niejawne przypisanie zmiennej!
|
||||
FTotal = FTrain - Sign(V) * FStand;
|
||||
}
|
||||
|
||||
double TMoverParameters::BrakeForceR(double ratio, double velocity)
|
||||
@@ -4235,175 +4182,121 @@ double TMoverParameters::Adhesive(double staticfriction) const
|
||||
return adhesion;
|
||||
}
|
||||
|
||||
// poprawka dla liczenia sil przy ustawieniu przeciwnym obiektow:
|
||||
/*
|
||||
double DirPatch(int Coupler1, int Coupler2)
|
||||
{
|
||||
if (Coupler1 != Coupler2) return 1;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
|
||||
double DirF(int CouplerN)
|
||||
{
|
||||
double rDirF;
|
||||
switch (CouplerN)
|
||||
{
|
||||
case 0: return -1; break;
|
||||
case 1: return 1; break;
|
||||
default: return 0;
|
||||
}
|
||||
// if (CouplerN == 0) return -1;
|
||||
// else if (CouplerN == 0) return 1;
|
||||
// else return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
// *************************************************************************************************
|
||||
// Q: 20160713
|
||||
// Obliczanie sił dzialających na sprzęgach
|
||||
// *************************************************************************************************
|
||||
double TMoverParameters::CouplerForce(int CouplerN, double dt)
|
||||
{
|
||||
// wyliczenie siły na sprzęgu
|
||||
double tempdist = 0, newdist = 0, distDelta = 0, CF = 0, dV = 0, absdV = 0, Fmax = 0;
|
||||
double BetaAvg = 0;
|
||||
int CNext = 0;
|
||||
const double MaxDist = 405.0; // ustawione + 5 m, bo skanujemy do 400 m
|
||||
const double MinDist = 0.5; // ustawione +.5 m, zeby nie rozlaczac przy malych odleglosciach
|
||||
const int MaxCount = 1500;
|
||||
bool rCF = false;
|
||||
// distDelta:=0; //Ra: value never used
|
||||
CNext = Couplers[CouplerN].ConnectedNr;
|
||||
// if (Couplers[CouplerN].CForce == 0) //nie bylo uzgadniane wiec policz
|
||||
double TMoverParameters::CouplerForce( int const End, double dt ) {
|
||||
|
||||
Couplers[CouplerN].CheckCollision = false;
|
||||
newdist = Couplers[CouplerN].CoupleDist; // odległość od sprzęgu sąsiada
|
||||
// newdist:=Distance(Loc,Connected^.Loc,Dim,Connected^.Dim);
|
||||
if (CouplerN == 0)
|
||||
{
|
||||
// ABu: bylo newdist+10*((...
|
||||
tempdist = ((Couplers[CouplerN].Connected->dMoveLen *
|
||||
DirPatch(0, Couplers[CouplerN].ConnectedNr)) -
|
||||
dMoveLen);
|
||||
newdist += 10.0 * tempdist;
|
||||
// tempdist:=tempdist+CoupleDist; //ABu: proby szybkiego naprawienia bledu
|
||||
}
|
||||
else
|
||||
{
|
||||
// ABu: bylo newdist+10*((...
|
||||
tempdist = ((dMoveLen - (Couplers[CouplerN].Connected->dMoveLen *
|
||||
DirPatch(1, Couplers[CouplerN].ConnectedNr))));
|
||||
newdist += 10.0 * tempdist;
|
||||
// tempdist:=tempdist+CoupleDist; //ABu: proby szybkiego naprawienia bledu
|
||||
}
|
||||
auto &coupler { Couplers[ End ] };
|
||||
auto *othervehicle { Neighbours[ End ].vehicle->MoverParameters };
|
||||
auto const otherend { Neighbours[ End ].vehicle_end };
|
||||
auto &othercoupler { othervehicle->Couplers[ otherend ] };
|
||||
|
||||
auto const othervehiclemove { ( othervehicle->dMoveLen * DirPatch( End, otherend ) ) };
|
||||
auto const distancedelta { (
|
||||
End == end::front ?
|
||||
othervehiclemove - dMoveLen :
|
||||
dMoveLen - othervehiclemove ) };
|
||||
auto const initialdistance { Neighbours[ End ].distance }; // odległość od sprzęgu sąsiada
|
||||
|
||||
auto const newdistance =
|
||||
initialdistance
|
||||
+ 10.0 * distancedelta;
|
||||
|
||||
auto const dV { V - ( othervehicle->V * DirPatch( End, otherend ) ) };
|
||||
auto const absdV { std::abs( dV ) };
|
||||
|
||||
dV = V - (double)DirPatch( CouplerN, CNext ) * Couplers[ CouplerN ].Connected->V;
|
||||
absdV = abs( dV );
|
||||
// potentially generate sounds on clash or stretch
|
||||
if( ( newdist < 0.0 )
|
||||
&& ( Couplers[ CouplerN ].Dist > newdist )
|
||||
if( ( newdistance < 0.0 )
|
||||
&& ( coupler.Dist > newdistance )
|
||||
&& ( dV < -0.5 ) ) {
|
||||
// 090503: dzwieki pracy zderzakow
|
||||
SetFlag(
|
||||
Couplers[ CouplerN ].sounds,
|
||||
coupler.sounds,
|
||||
( absdV > 5.0 ?
|
||||
( sound::bufferclash | sound::loud ) :
|
||||
sound::bufferclash ) );
|
||||
}
|
||||
else if( ( Couplers[ CouplerN ].CouplingFlag != coupling::faux )
|
||||
&& ( newdist > 0.001 )
|
||||
&& ( Couplers[ CouplerN ].Dist <= 0.001 )
|
||||
else if( ( coupler.CouplingFlag != coupling::faux )
|
||||
&& ( newdistance > 0.001 )
|
||||
&& ( coupler.Dist <= 0.001 )
|
||||
&& ( absdV > 0.005 )
|
||||
&& ( Vel > 1.0 ) ) {
|
||||
// 090503: dzwieki pracy sprzegu
|
||||
SetFlag(
|
||||
Couplers[ CouplerN ].sounds,
|
||||
coupler.sounds,
|
||||
( absdV > 0.035 ?
|
||||
( sound::couplerstretch | sound::loud ) :
|
||||
sound::couplerstretch ) );
|
||||
}
|
||||
|
||||
// blablabla
|
||||
// ABu: proby znalezienia problemu ze zle odbijajacymi sie skladami
|
||||
//if (Couplers[CouplerN].CouplingFlag=ctrain_virtual) and (newdist>0) then
|
||||
if( ( Couplers[ CouplerN ].CouplingFlag != coupling::faux )
|
||||
|| ( Couplers[ CouplerN ].CoupleDist < 0 ) ) {
|
||||
coupler.CheckCollision = false;
|
||||
double CF { 0.0 };
|
||||
|
||||
if( Couplers[ CouplerN ].CouplingFlag == coupling::faux ) {
|
||||
if( ( coupler.CouplingFlag != coupling::faux )
|
||||
|| ( initialdistance < 0 ) ) {
|
||||
|
||||
BetaAvg = Couplers[CouplerN].beta;
|
||||
Fmax = (Couplers[CouplerN].FmaxC + Couplers[CouplerN].FmaxB) * CouplerTune;
|
||||
double BetaAvg = 0;
|
||||
double Fmax = 0;
|
||||
|
||||
if( coupler.CouplingFlag == coupling::faux ) {
|
||||
|
||||
BetaAvg = coupler.beta;
|
||||
Fmax = (coupler.FmaxC + coupler.FmaxB) * CouplerTune;
|
||||
}
|
||||
else // usrednij bo wspolny sprzeg
|
||||
{
|
||||
BetaAvg =
|
||||
(Couplers[CouplerN].beta + Couplers[CouplerN].Connected->Couplers[CNext].beta) /
|
||||
2.0;
|
||||
Fmax = (Couplers[CouplerN].FmaxC + Couplers[CouplerN].FmaxB +
|
||||
Couplers[CouplerN].Connected->Couplers[CNext].FmaxC +
|
||||
Couplers[CouplerN].Connected->Couplers[CNext].FmaxB) *
|
||||
CouplerTune / 2.0;
|
||||
else {
|
||||
// usrednij bo wspolny sprzeg
|
||||
BetaAvg = 0.5 * ( coupler.beta + othercoupler.beta );
|
||||
Fmax = 0.5 * ( coupler.FmaxC + coupler.FmaxB + othercoupler.FmaxC + othercoupler.FmaxB ) * CouplerTune;
|
||||
}
|
||||
distDelta =
|
||||
abs(newdist) - abs(Couplers[CouplerN].Dist); // McZapkie-191103: poprawka na histereze
|
||||
Couplers[CouplerN].Dist = newdist;
|
||||
if (Couplers[CouplerN].Dist > 0)
|
||||
{
|
||||
if (distDelta > 0)
|
||||
CF = (-(Couplers[CouplerN].SpringKC +
|
||||
Couplers[CouplerN].Connected->Couplers[CNext].SpringKC) *
|
||||
Couplers[CouplerN].Dist / 2.0) *
|
||||
DirF(CouplerN) -
|
||||
Fmax * dV * BetaAvg;
|
||||
else
|
||||
CF = (-(Couplers[CouplerN].SpringKC +
|
||||
Couplers[CouplerN].Connected->Couplers[CNext].SpringKC) *
|
||||
Couplers[CouplerN].Dist / 2.0) *
|
||||
DirF(CouplerN) * BetaAvg -
|
||||
Fmax * dV * BetaAvg;
|
||||
auto const distDelta { std::abs( newdistance ) - std::abs( coupler.Dist ) }; // McZapkie-191103: poprawka na histereze
|
||||
coupler.Dist = newdistance;
|
||||
if (coupler.Dist > 0) {
|
||||
|
||||
if( distDelta > 0 ) {
|
||||
CF = ( -( coupler.SpringKC + othercoupler.SpringKC ) * coupler.Dist / 2.0 ) * DirF( End )
|
||||
- Fmax * dV * BetaAvg;
|
||||
}
|
||||
else {
|
||||
CF = ( -( coupler.SpringKC + othercoupler.SpringKC ) * coupler.Dist / 2.0 ) * DirF( End ) * BetaAvg
|
||||
- Fmax * dV * BetaAvg;
|
||||
}
|
||||
// liczenie sily ze sprezystosci sprzegu
|
||||
if (Couplers[CouplerN].Dist >
|
||||
(Couplers[CouplerN].DmaxC +
|
||||
Couplers[CouplerN].Connected->Couplers[CNext].DmaxC)) // zderzenie
|
||||
//***if tempdist>(DmaxC+Connected^.Couplers[CNext].DmaxC) then {zderzenie}
|
||||
Couplers[CouplerN].CheckCollision = true;
|
||||
if( coupler.Dist > ( coupler.DmaxC + othercoupler.DmaxC ) ) {
|
||||
// zderzenie
|
||||
coupler.CheckCollision = true;
|
||||
}
|
||||
}
|
||||
if (Couplers[CouplerN].Dist < 0)
|
||||
{
|
||||
if (distDelta > 0)
|
||||
CF = (-(Couplers[CouplerN].SpringKB +
|
||||
Couplers[CouplerN].Connected->Couplers[CNext].SpringKB) *
|
||||
Couplers[CouplerN].Dist / 2.0) *
|
||||
DirF(CouplerN) -
|
||||
Fmax * dV * BetaAvg;
|
||||
else
|
||||
CF = (-(Couplers[CouplerN].SpringKB +
|
||||
Couplers[CouplerN].Connected->Couplers[CNext].SpringKB) *
|
||||
Couplers[CouplerN].Dist / 2.0) *
|
||||
DirF(CouplerN) * BetaAvg -
|
||||
Fmax * dV * BetaAvg;
|
||||
if( coupler.Dist < 0 ) {
|
||||
|
||||
if( distDelta > 0 ) {
|
||||
CF = ( -( coupler.SpringKB + othercoupler.SpringKB ) * coupler.Dist / 2.0 ) * DirF( End )
|
||||
- Fmax * dV * BetaAvg;
|
||||
}
|
||||
else {
|
||||
CF = ( -( coupler.SpringKB + othercoupler.SpringKB ) * coupler.Dist / 2.0 ) * DirF( End ) * BetaAvg
|
||||
- Fmax * dV * BetaAvg;
|
||||
}
|
||||
// liczenie sily ze sprezystosci zderzaka
|
||||
if (-Couplers[CouplerN].Dist >
|
||||
(Couplers[CouplerN].DmaxB +
|
||||
Couplers[CouplerN].Connected->Couplers[CNext].DmaxB)) // zderzenie
|
||||
//***if -tempdist>(DmaxB+Connected^.Couplers[CNext].DmaxB)/10 then {zderzenie}
|
||||
{
|
||||
Couplers[CouplerN].CheckCollision = true;
|
||||
if( ( Couplers[ CouplerN ].CouplerType == TCouplerType::Automatic )
|
||||
&& ( Couplers[ CouplerN ].CouplingFlag == coupling::faux ) ) {
|
||||
// sprzeganie wagonow z samoczynnymi sprzegami}
|
||||
// CouplingFlag:=ctrain_coupler+ctrain_pneumatic+ctrain_controll+ctrain_passenger+ctrain_scndpneumatic;
|
||||
if( -coupler.Dist > ( coupler.DmaxB + othercoupler.DmaxB ) ) {
|
||||
// zderzenie
|
||||
coupler.CheckCollision = true;
|
||||
if( ( coupler.CouplerType == TCouplerType::Automatic )
|
||||
&& ( coupler.CouplingFlag == coupling::faux ) ) {
|
||||
// sprzeganie wagonow z samoczynnymi sprzegami
|
||||
// EN57
|
||||
Couplers[ CouplerN ].CouplingFlag = coupling::coupler /*| coupling::brakehose | coupling::mainhose | coupling::control*/;
|
||||
SetFlag( Couplers[ CouplerN ].sounds, sound::attachcoupler );
|
||||
// TBD, TODO: configurable flag for automatic coupling
|
||||
coupler.CouplingFlag = coupling::coupler /*| coupling::brakehose | coupling::mainhose | coupling::control*/;
|
||||
SetFlag( coupler.sounds, sound::attachcoupler );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( Couplers[ CouplerN ].CouplingFlag != coupling::faux ) {
|
||||
|
||||
if( coupler.CouplingFlag != coupling::faux ) {
|
||||
// uzgadnianie prawa Newtona
|
||||
Couplers[ CouplerN ].Connected->Couplers[ 1 - CouplerN ].CForce = -CF;
|
||||
othervehicle->Couplers[ 1 - End ].CForce = -CF;
|
||||
}
|
||||
|
||||
return CF;
|
||||
@@ -5314,7 +5207,7 @@ double TMoverParameters::TractionForce( double dt ) {
|
||||
// Q: 20160713
|
||||
//Obliczenie predkości obrotowej kół???
|
||||
// *************************************************************************************************
|
||||
double TMoverParameters::ComputeRotatingWheel(double WForce, double dt, double n)
|
||||
double TMoverParameters::ComputeRotatingWheel(double WForce, double dt, double n) const
|
||||
{
|
||||
double newn = 0, eps = 0;
|
||||
if ((n == 0) && (WForce * Sign(V) < 0))
|
||||
@@ -7150,17 +7043,16 @@ double TMoverParameters::GetTrainsetVoltage(void)
|
||||
// *************************************************************************************************
|
||||
// Kasowanie zmiennych pracy fizyki
|
||||
// *************************************************************************************************
|
||||
bool TMoverParameters::Physic_ReActivation(void) // DO PRZETLUMACZENIA NA KONCU
|
||||
bool TMoverParameters::switch_physics(bool const State) // DO PRZETLUMACZENIA NA KONCU
|
||||
{
|
||||
// bool pr;
|
||||
if (PhysicActivation)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
PhysicActivation = true;
|
||||
if( PhysicActivation == State ) { return false; }
|
||||
|
||||
PhysicActivation = State;
|
||||
if( true == State ) {
|
||||
LastSwitchingTime = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
@@ -9970,8 +9862,7 @@ bool TMoverParameters::RunInternalCommand()
|
||||
CommandIn.Location.X = 0;
|
||||
CommandIn.Location.Y = 0;
|
||||
CommandIn.Location.Z = 0;
|
||||
if (!PhysicActivation)
|
||||
Physic_ReActivation();
|
||||
switch_physics( true );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
63
Train.cpp
63
Train.cpp
@@ -4867,11 +4867,11 @@ void TTrain::OnCommand_cabchangeforward( TTrain *Train, command_data const &Comm
|
||||
if( false == Train->CabChange( 1 ) ) {
|
||||
if( TestFlag( Train->DynamicObject->MoverParameters->Couplers[ end::front ].CouplingFlag, coupling::gangway ) ) {
|
||||
// przejscie do nastepnego pojazdu
|
||||
Global.changeDynObj = Train->DynamicObject->PrevConnected;
|
||||
Global.changeDynObj = Train->DynamicObject->PrevConnected();
|
||||
Global.changeDynObj->MoverParameters->ActiveCab = (
|
||||
Train->DynamicObject->PrevConnectedNo ?
|
||||
-1 :
|
||||
1 );
|
||||
Train->DynamicObject->MoverParameters->Neighbours[end::front].vehicle_end ?
|
||||
-1 :
|
||||
1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4883,11 +4883,11 @@ void TTrain::OnCommand_cabchangebackward( TTrain *Train, command_data const &Com
|
||||
if( false == Train->CabChange( -1 ) ) {
|
||||
if( TestFlag( Train->DynamicObject->MoverParameters->Couplers[ end::rear ].CouplingFlag, coupling::gangway ) ) {
|
||||
// przejscie do nastepnego pojazdu
|
||||
Global.changeDynObj = Train->DynamicObject->NextConnected;
|
||||
Global.changeDynObj = Train->DynamicObject->NextConnected();
|
||||
Global.changeDynObj->MoverParameters->ActiveCab = (
|
||||
Train->DynamicObject->NextConnectedNo ?
|
||||
-1 :
|
||||
1 );
|
||||
Train->DynamicObject->MoverParameters->Neighbours[end::rear].vehicle_end ?
|
||||
-1 :
|
||||
1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5260,14 +5260,14 @@ bool TTrain::Update( double const Deltatime )
|
||||
{
|
||||
TDynamicObject *tmp;
|
||||
tmp = NULL;
|
||||
if (DynamicObject->NextConnected)
|
||||
if (DynamicObject->NextConnected())
|
||||
if ((TestFlag(mvControlled->Couplers[1].CouplingFlag, ctrain_controll)) &&
|
||||
(mvOccupied->ActiveCab == 1))
|
||||
tmp = DynamicObject->NextConnected;
|
||||
if (DynamicObject->PrevConnected)
|
||||
tmp = DynamicObject->NextConnected();
|
||||
if (DynamicObject->PrevConnected())
|
||||
if ((TestFlag(mvControlled->Couplers[0].CouplingFlag, ctrain_controll)) &&
|
||||
(mvOccupied->ActiveCab == -1))
|
||||
tmp = DynamicObject->PrevConnected;
|
||||
tmp = DynamicObject->PrevConnected();
|
||||
if( tmp ) {
|
||||
if( tmp->MoverParameters->Power > 0 ) {
|
||||
if( ggI1B.SubModel ) {
|
||||
@@ -5668,10 +5668,10 @@ bool TTrain::Update( double const Deltatime )
|
||||
tmp = NULL;
|
||||
if ((TestFlag(mvControlled->Couplers[1].CouplingFlag, ctrain_controll)) &&
|
||||
(mvOccupied->ActiveCab > 0))
|
||||
tmp = DynamicObject->NextConnected;
|
||||
tmp = DynamicObject->NextConnected();
|
||||
if ((TestFlag(mvControlled->Couplers[0].CouplingFlag, ctrain_controll)) &&
|
||||
(mvOccupied->ActiveCab < 0))
|
||||
tmp = DynamicObject->PrevConnected;
|
||||
tmp = DynamicObject->PrevConnected();
|
||||
|
||||
if (tmp)
|
||||
if ( mvControlled->Battery || mvControlled->ConverterFlag ) {
|
||||
@@ -6954,26 +6954,25 @@ void TTrain::DynamicSet(TDynamicObject *d)
|
||||
mvOccupied = mvControlled = d ? DynamicObject->MoverParameters : NULL; // albo silnikowy w EZT
|
||||
if (!DynamicObject)
|
||||
return;
|
||||
if (mvControlled->TrainType & dt_EZT) // na razie dotyczy to EZT
|
||||
if (DynamicObject->NextConnected ? mvControlled->Couplers[1].AllowedFlag & ctrain_depot :
|
||||
false)
|
||||
{ // gdy jest człon od sprzęgu 1, a sprzęg łączony
|
||||
// warsztatowo (powiedzmy)
|
||||
if ((mvControlled->Power < 1.0) && (mvControlled->Couplers[1].Connected->Power >
|
||||
1.0)) // my nie mamy mocy, ale ten drugi ma
|
||||
mvControlled =
|
||||
DynamicObject->NextConnected->MoverParameters; // będziemy sterować tym z mocą
|
||||
// TODO: leverage code already present in TDynamicObject::ControlledFind()
|
||||
if( ( d->MoverParameters->TrainType == dt_EZT )
|
||||
|| ( d->MoverParameters->TrainType == dt_DMU ) ) {
|
||||
|
||||
if( ( d->NextConnected() != nullptr )
|
||||
&& ( true == TestFlag( d->MoverParameters->Couplers[ end::rear ].AllowedFlag, coupling::permanent ) ) ) {
|
||||
if( ( mvControlled->Power < 1.0 ) && ( mvControlled->Couplers[ 1 ].Connected->Power > 1.0 ) ) {
|
||||
// my nie mamy mocy, ale ten drugi ma
|
||||
mvControlled = DynamicObject->NextConnected()->MoverParameters; // będziemy sterować tym z mocą
|
||||
}
|
||||
}
|
||||
else if (DynamicObject->PrevConnected ?
|
||||
mvControlled->Couplers[0].AllowedFlag & ctrain_depot :
|
||||
false)
|
||||
{ // gdy jest człon od sprzęgu 0, a sprzęg łączony
|
||||
// warsztatowo (powiedzmy)
|
||||
if ((mvControlled->Power < 1.0) && (mvControlled->Couplers[0].Connected->Power >
|
||||
1.0)) // my nie mamy mocy, ale ten drugi ma
|
||||
mvControlled =
|
||||
DynamicObject->PrevConnected->MoverParameters; // będziemy sterować tym z mocą
|
||||
else if( ( d->PrevConnected() != nullptr )
|
||||
&& ( true == TestFlag( d->MoverParameters->Couplers[ end::front ].AllowedFlag, coupling::permanent ) ) ) {
|
||||
if( ( mvControlled->Power < 1.0 ) && ( mvControlled->Couplers[ 0 ].Connected->Power > 1.0 ) ) {
|
||||
// my nie mamy mocy, ale ten drugi ma
|
||||
mvControlled = DynamicObject->PrevConnected()->MoverParameters; // będziemy sterować tym z mocą
|
||||
}
|
||||
}
|
||||
}
|
||||
mvSecond = NULL; // gdyby się nic nie znalazło
|
||||
if (mvOccupied->Power > 1.0) // dwuczłonowe lub ukrotnienia, żeby nie szukać każdorazowo
|
||||
if (mvOccupied->Couplers[1].Connected ?
|
||||
|
||||
@@ -218,8 +218,7 @@ timetable_panel::update() {
|
||||
auto consistmass { owner->fMass };
|
||||
auto consistlength { owner->fLength };
|
||||
if( ( owner->mvControlling->TrainType != dt_DMU )
|
||||
&& ( owner->mvControlling->TrainType != dt_EZT )
|
||||
&& ( owner->pVehicles[end::front] != owner->pVehicles[end::rear] ) ) {
|
||||
&& ( owner->mvControlling->TrainType != dt_EZT ) ) {
|
||||
//odejmij lokomotywy czynne, a przynajmniej aktualną
|
||||
consistmass -= owner->pVehicle->MoverParameters->TotalMass;
|
||||
// subtract potential other half of a two-part vehicle
|
||||
@@ -227,7 +226,6 @@ timetable_panel::update() {
|
||||
if( previous != nullptr ) { consistmass -= previous->MoverParameters->TotalMass; }
|
||||
auto const *next { owner->pVehicle->NextC( coupling::permanent ) };
|
||||
if( next != nullptr ) { consistmass -= next->MoverParameters->TotalMass; }
|
||||
// consistlength -= owner->pVehicle->MoverParameters->Dim.L;
|
||||
}
|
||||
std::snprintf(
|
||||
m_buffer.data(), m_buffer.size(),
|
||||
@@ -563,10 +561,7 @@ debug_panel::update_vehicle_coupler( int const Side ) {
|
||||
// NOTE: mover and vehicle are guaranteed to be valid by the caller
|
||||
std::string couplerstatus { locale::strings[ locale::string::debug_vehicle_none ] };
|
||||
|
||||
auto const *connected { (
|
||||
Side == end::front ?
|
||||
m_input.vehicle->PrevConnected :
|
||||
m_input.vehicle->NextConnected ) };
|
||||
auto const *connected { m_input.vehicle->MoverParameters->Neighbours[ Side ].vehicle };
|
||||
|
||||
if( connected == nullptr ) { return couplerstatus; }
|
||||
|
||||
@@ -574,10 +569,10 @@ debug_panel::update_vehicle_coupler( int const Side ) {
|
||||
|
||||
std::snprintf(
|
||||
m_buffer.data(), m_buffer.size(),
|
||||
"%s [%d]%s",
|
||||
"%s [%d] (%.1f m)",
|
||||
connected->name().c_str(),
|
||||
mover.Couplers[ Side ].CouplingFlag,
|
||||
std::string( mover.Couplers[ Side ].CouplingFlag == 0 ? " (" + to_string( mover.Couplers[ Side ].CoupleDist, 1 ) + " m)" : "" ).c_str() );
|
||||
mover.Neighbours[ Side ].distance );
|
||||
|
||||
return { m_buffer.data() };
|
||||
}
|
||||
@@ -700,6 +695,10 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
|
||||
"Distances:\n proximity: " + to_string( mechanik.ActualProximityDist, 0 )
|
||||
+ ", braking: " + to_string( mechanik.fBrakeDist, 0 );
|
||||
|
||||
if( mechanik.Obstacle.distance < 5000 ) {
|
||||
textline += "\n obstacle: " + to_string( mechanik.Obstacle.distance, 0 );
|
||||
}
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
// velocity factors
|
||||
|
||||
Reference in New Issue
Block a user