mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-21 14:49:19 +02: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 ) {
|
if( mvOccupied->Vel < 2.0 ) {
|
||||||
// stanąć nie musi, ale zwolnić przynajmniej
|
// stanąć nie musi, ale zwolnić przynajmniej
|
||||||
if( ( sSpeedTable[ i ].fDist < fMaxProximityDist )
|
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ć)
|
// 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
|
// as long as there isn't any obstacle in arbitrary view range
|
||||||
eSignSkip = sSpeedTable[ i ].evEvent;
|
eSignSkip = sSpeedTable[ i ].evEvent;
|
||||||
@@ -1259,7 +1259,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
|
|
||||||
//sprawdzenie eventów pasywnych przed nami
|
//sprawdzenie eventów pasywnych przed nami
|
||||||
if( ( mvOccupied->CategoryFlag & 1 )
|
if( ( mvOccupied->CategoryFlag & 1 )
|
||||||
&& ( sSpeedTable[ i ].fDist > pVehicles[ 0 ]->fTrackBlock - 20.0 ) ) {
|
&& ( sSpeedTable[ i ].fDist > Obstacle.distance - 20 ) ) {
|
||||||
// jak sygnał jest dalej niż zawalidroga
|
// jak sygnał jest dalej niż zawalidroga
|
||||||
v = 0.0; // to może być podany dla tamtego: jechać tak, jakby tam stop był
|
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 ) ) {
|
&& ( p->MoverParameters->BrakeSubsystem != TBrakeSubSystem::ss_LSt ) ) {
|
||||||
iDrivigFlags &= ~( moveOerlikons );
|
iDrivigFlags &= ~( moveOerlikons );
|
||||||
}
|
}
|
||||||
p = p->Neightbour(dir); // pojazd podłączony od wskazanej strony
|
p = p->Neighbour(dir); // pojazd podłączony od wskazanej strony
|
||||||
}
|
}
|
||||||
if (main)
|
if (main)
|
||||||
iDrivigFlags |= movePrimary; // nie znaleziono innego, można się porządzić
|
iDrivigFlags |= movePrimary; // nie znaleziono innego, można się porządzić
|
||||||
@@ -2408,11 +2408,11 @@ bool TController::PrepareEngine()
|
|||||||
if( !iDirection ) {
|
if( !iDirection ) {
|
||||||
// jeśli nie ma ustalonego kierunku
|
// jeśli nie ma ustalonego kierunku
|
||||||
if( ( mvControlling->PantFrontVolt != 0.0 ) || ( mvControlling->PantRearVolt != 0.0 ) || voltfront || voltrear ) {
|
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
|
// jeśli z tyłu nie ma nic
|
||||||
iDirection = -1; // jazda w kierunku sprzęgu 1
|
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
|
// jeśli z przodu nie ma nic
|
||||||
iDirection = 1; // jazda w kierunku sprzęgu 0
|
iDirection = 1; // jazda w kierunku sprzęgu 0
|
||||||
}
|
}
|
||||||
@@ -2618,12 +2618,12 @@ bool TController::IncBrake()
|
|||||||
|| ( mvOccupied->TrainType == dt_ET42 ) ) {
|
|| ( mvOccupied->TrainType == dt_ET42 ) ) {
|
||||||
// NOTE: we're doing simplified checks full of presuptions here.
|
// NOTE: we're doing simplified checks full of presuptions here.
|
||||||
// they'll break if someone does strange thing like turning around the second unit
|
// they'll break if someone does strange thing like turning around the second unit
|
||||||
if( ( mvOccupied->Couplers[ 1 ].CouplingFlag & coupling::permanent )
|
if( ( mvOccupied->Couplers[ end::rear ].CouplingFlag & coupling::permanent )
|
||||||
&& ( mvOccupied->Couplers[ 1 ].Connected->Couplers[ 1 ].CouplingFlag > 0 ) ) {
|
&& ( mvOccupied->Couplers[ end::rear ].Connected->Couplers[ end::rear ].Connected != nullptr ) ) {
|
||||||
standalone = false;
|
standalone = false;
|
||||||
}
|
}
|
||||||
if( ( mvOccupied->Couplers[ 0 ].CouplingFlag & coupling::permanent )
|
if( ( mvOccupied->Couplers[ end::front ].CouplingFlag & coupling::permanent )
|
||||||
&& ( mvOccupied->Couplers[ 0 ].Connected->Couplers[ 0 ].CouplingFlag > 0 ) ) {
|
&& ( mvOccupied->Couplers[ end::front ].Connected->Couplers[ end::front ].Connected != nullptr ) ) {
|
||||||
standalone = false;
|
standalone = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2637,16 +2637,16 @@ bool TController::IncBrake()
|
|||||||
( ( mvOccupied->Couplers[ 0 ].CouplingFlag == 0 )
|
( ( mvOccupied->Couplers[ 0 ].CouplingFlag == 0 )
|
||||||
&& ( mvOccupied->Couplers[ 1 ].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
|
// 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 )
|
while( ( true == standalone )
|
||||||
&& ( vehicle != nullptr ) ) {
|
&& ( vehicle != nullptr ) ) {
|
||||||
// NOTE: we could simplify this by doing only check of the rear coupler, but this can be quite tricky in itself
|
// 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
|
// TODO: add easier ways to access front/rear coupler taking into account vehicle's direction
|
||||||
standalone =
|
standalone =
|
||||||
( ( ( vehicle->MoverParameters->Couplers[ 0 ].CouplingFlag == 0 ) || ( vehicle->MoverParameters->Couplers[ 0 ].CouplingFlag & coupling::control ) )
|
( ( ( vehicle->MoverParameters->Couplers[ end::front ].Connected == nullptr ) || ( vehicle->MoverParameters->Couplers[ end::front ].CouplingFlag & coupling::control ) )
|
||||||
&& ( ( vehicle->MoverParameters->Couplers[ 1 ].CouplingFlag == 0 ) || ( vehicle->MoverParameters->Couplers[ 1 ].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)
|
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
|
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
|
else { // if (NewValue2==0.0) //zerowy sprzęg
|
||||||
if (NewValue1 >= 0.0) // jeśli ilość wagonów inna niż wszystkie
|
if( NewValue1 >= 0.0 ) {
|
||||||
{ // będzie odczepianie, ale jeśli wagony są z przodu, to trzeba najpierw zmienić kierunek
|
// jeśli ilość wagonów inna niż wszystkie będzie odczepianie,
|
||||||
if ((mvOccupied->Couplers[mvOccupied->DirAbsolute > 0 ? 1 : 0].CouplingFlag ==
|
// ale jeśli wagony są z przodu, to trzeba najpierw zmienić kierunek
|
||||||
0) ? // z tyłu nic
|
if( ( mvOccupied->Couplers[ mvOccupied->DirAbsolute > 0 ? end::rear : end::front ].Connected == nullptr ) // z tyłu nic
|
||||||
(mvOccupied->Couplers[mvOccupied->DirAbsolute > 0 ? 0 : 1].CouplingFlag > 0) :
|
&& ( mvOccupied->Couplers[ mvOccupied->DirAbsolute > 0 ? end::front : end::rear ].Connected != nullptr ) ) { // a z przodu skład
|
||||||
false) // a z przodu skład
|
iDirectionOrder = -iDirection; // zmiana na ciągnięcie
|
||||||
{
|
OrderNext( Change_direction ); // najpierw zmień kierunek (zastąpi Disconnect)
|
||||||
iDirectionOrder = -iDirection; // zmiana na ciągnięcie
|
OrderPush( Disconnect ); // a odczep już po zmianie kierunku
|
||||||
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)
|
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
|
// 8. Ustalić częstotliwość świadomości AI (zatrzymanie precyzyjne - częściej, brak atrakcji
|
||||||
// - rzadziej).
|
// - rzadziej).
|
||||||
|
|
||||||
// check for potential colliders
|
// check for potential collisions
|
||||||
{
|
{
|
||||||
auto rearvehicle = (
|
// HACK: vehicle order in the consist is based on intended travel direction
|
||||||
pVehicles[ 0 ] == pVehicles[ 1 ] ?
|
// if our actual travel direction doesn't match that, we should be scanning from the other end of the consist
|
||||||
pVehicles[ 0 ] :
|
auto *frontvehicle { pVehicles[ ( mvOccupied->V * iDirection >= 0 ? end::front : end::rear ) ] };
|
||||||
pVehicles[ 1 ] );
|
|
||||||
|
int routescandirection;
|
||||||
// for moving vehicle determine heading from velocity; for standing fall back on the set direction
|
// 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 :
|
iDirection > 0 :
|
||||||
mvOccupied->V > 0.0 ) ) {
|
iDirection < 0 ) ) ) {
|
||||||
// towards coupler 0
|
// towards coupler 0
|
||||||
if( ( mvOccupied->V * iDirection < 0.0 )
|
routescandirection = end::front;
|
||||||
|| ( ( 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 );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// towards coupler 1
|
// towards coupler 1
|
||||||
if( ( mvOccupied->V * iDirection < 0.0 )
|
routescandirection = end::rear;
|
||||||
|| ( ( 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
|
Obstacle = neighbour_data();
|
||||||
rearvehicle->ABuScanObjects( (
|
auto const lookup { frontvehicle->find_vehicle( routescandirection, routescanrange ) };
|
||||||
pVehicle->DirectionGet() == rearvehicle->DirectionGet() ?
|
|
||||||
1 :
|
if( std::get<bool>( lookup ) == true ) {
|
||||||
-1 ),
|
|
||||||
fMaxProximityDist );
|
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() ?
|
else {
|
||||||
-1 :
|
Obstacle.distance = 10000; // legacy value. TBD, TODO: use standard -1 instead?
|
||||||
1 ),
|
|
||||||
routescanrange );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// tu bedzie logika sterowania
|
// tu bedzie logika sterowania
|
||||||
if (AIControllFlag) {
|
if (AIControllFlag) {
|
||||||
|
|
||||||
@@ -4291,37 +4280,17 @@ TController::UpdateSituation(double dt) {
|
|||||||
if (AIControllFlag)
|
if (AIControllFlag)
|
||||||
{ // to robi tylko AI, wersję dla człowieka trzeba dopiero zrobić
|
{ // to robi tylko AI, wersję dla człowieka trzeba dopiero zrobić
|
||||||
// sprzęgi sprawdzamy w pierwszej kolejności, bo jak połączony, to koniec
|
// 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)
|
auto *vehicle { pVehicles[ end::front ] };
|
||||||
if (pVehicles[0]->DirectionGet() > 0) // jeśli sprzęg 0
|
auto *vehicleparameters { vehicle->MoverParameters };
|
||||||
{ // sprzęg 0 - próba podczepienia
|
int const end { ( vehicle->DirectionGet() > 0 ? end::front : end::rear ) };
|
||||||
if( pVehicles[ 0 ]->MoverParameters->Couplers[ 0 ].Connected ) {
|
auto const &neighbour { vehicleparameters->Neighbours[ end ] };
|
||||||
// jeśli jest coś wykryte (a chyba jest, nie?)
|
// próba podczepienia
|
||||||
if( pVehicles[ 0 ]->MoverParameters->Attach(
|
vehicleparameters->Attach(
|
||||||
0, 2, pVehicles[ 0 ]->MoverParameters->Couplers[ 0 ].Connected,
|
end, neighbour.vehicle_end,
|
||||||
iCoupler ) ) {
|
neighbour.vehicle->MoverParameters,
|
||||||
// pVehicles[0]->dsbCouplerAttach->SetVolume(DSBVOLUME_MAX);
|
iCoupler );
|
||||||
// pVehicles[0]->dsbCouplerAttach->Play(0,0,0);
|
if( vehicleparameters->Couplers[ end ].CouplingFlag == iCoupler ) {
|
||||||
}
|
// jeżeli został podłączony
|
||||||
}
|
|
||||||
// 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
|
|
||||||
iCoupler = 0; // dalsza jazda manewrowa już bez łączenia
|
iCoupler = 0; // dalsza jazda manewrowa już bez łączenia
|
||||||
iDrivigFlags &= ~moveConnect; // zdjęcie flagi doczepiania
|
iDrivigFlags &= ~moveConnect; // zdjęcie flagi doczepiania
|
||||||
SetVelocity(0, 0, stopJoin); // wyłączyć przyspieszanie
|
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ąć
|
fMaxProximityDist = 5.0; //[m] w takim przedziale odległości powinien stanąć
|
||||||
fVelPlus = 2.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania
|
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
|
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
|
// przy zderzeniu fTrackBlock nie jest miarodajne
|
||||||
// początek podczepiania, z wyłączeniem sprawdzania fTrackBlock
|
// początek podczepiania, z wyłączeniem sprawdzania fTrackBlock
|
||||||
iDrivigFlags |= moveConnect;
|
iDrivigFlags |= moveConnect;
|
||||||
@@ -4477,8 +4446,8 @@ TController::UpdateSituation(double dt) {
|
|||||||
&& ( false == TestFlag( iDrivigFlags, movePress ) )
|
&& ( false == TestFlag( iDrivigFlags, movePress ) )
|
||||||
&& ( iCoupler == 0 )
|
&& ( iCoupler == 0 )
|
||||||
// && ( mvOccupied->Vel > 0.0 )
|
// && ( mvOccupied->Vel > 0.0 )
|
||||||
&& ( pVehicle->MoverParameters->Couplers[ end::front ].CouplingFlag == coupling::faux )
|
&& ( pVehicle->MoverParameters->Couplers[ end::front ].Connected == nullptr )
|
||||||
&& ( pVehicle->MoverParameters->Couplers[ end::rear ].CouplingFlag == coupling::faux ) ) {
|
&& ( pVehicle->MoverParameters->Couplers[ end::rear ].Connected == nullptr ) ) {
|
||||||
SetVelocity(0, 0, stopJoin); // 1. faza odczepiania: zatrzymanie
|
SetVelocity(0, 0, stopJoin); // 1. faza odczepiania: zatrzymanie
|
||||||
// WriteLog("Zatrzymanie w celu odczepienia");
|
// WriteLog("Zatrzymanie w celu odczepienia");
|
||||||
AccPreferred = std::min( 0.0, AccPreferred );
|
AccPreferred = std::min( 0.0, AccPreferred );
|
||||||
@@ -4516,7 +4485,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
else
|
else
|
||||||
{ // samochód ma stać, aż dostanie odjazd, chyba że stoi przez kolizję
|
{ // samochód ma stać, aż dostanie odjazd, chyba że stoi przez kolizję
|
||||||
if (eStopReason == stopBlock)
|
if (eStopReason == stopBlock)
|
||||||
if (pVehicles[0]->fTrackBlock > fDriverDist)
|
if (Obstacle.distance > fDriverDist)
|
||||||
if (AIControllFlag)
|
if (AIControllFlag)
|
||||||
{
|
{
|
||||||
PrepareEngine(); // zmieni ustawiony kierunek
|
PrepareEngine(); // zmieni ustawiony kierunek
|
||||||
@@ -4668,7 +4637,8 @@ TController::UpdateSituation(double dt) {
|
|||||||
n = 0; // nie ma co dalej sprawdzać, doczepianie zakończone
|
n = 0; // nie ma co dalej sprawdzać, doczepianie zakończone
|
||||||
}
|
}
|
||||||
} while (n--);
|
} 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
|
// no target, or already just virtual coupling
|
||||||
WriteLog( mvOccupied->Name + " didn't find anything to disconnect." );
|
WriteLog( mvOccupied->Name + " didn't find anything to disconnect." );
|
||||||
iVehicleCount = -2; // odczepiono, co było do odczepienia
|
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
|
// 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
|
// 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
|
// było porównać z odległością od sygnalizatora z przodu
|
||||||
if( ( OrderList[ OrderPos ] & Connect ) ?
|
if( ( ( OrderList[ OrderPos ] & Connect ) == 0 )
|
||||||
( pVehicles[ 0 ]->fTrackBlock > 2000 || pVehicles[ 0 ]->fTrackBlock > FirstSemaphorDist ) :
|
|| ( Obstacle.distance > std::min( 2000.0, FirstSemaphorDist ) ) ) {
|
||||||
true ) {
|
|
||||||
if( ( comm = BackwardScan() ) != TCommandType::cm_Unknown ) {
|
if( ( comm = BackwardScan() ) != TCommandType::cm_Unknown ) {
|
||||||
// jeśli w drugą można jechać
|
// jeśli w drugą można jechać
|
||||||
// należy sprawdzać odległość od znalezionego sygnalizatora,
|
// 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ą
|
VelDesired = fVelMax; // bo VelDesired<0 oznacza prędkość maksymalną
|
||||||
|
|
||||||
// Ra: jazda na widoczność
|
// Ra: jazda na widoczność
|
||||||
/*
|
if( Obstacle.distance < 5000 ) {
|
||||||
// condition disabled, it'd prevent setting reduced acceleration in the last connect stage
|
// mamy coś z przodu
|
||||||
if ((iDrivigFlags & moveConnect) == 0) // przy końcówce podłączania nie hamować
|
// prędkość pojazdu z przodu (zakładając, że jedzie w tę samą stronę!!!)
|
||||||
*/
|
auto const k { Obstacle.vehicle->MoverParameters->Vel };
|
||||||
{ // sprawdzenie jazdy na widoczność
|
if( k - vel < 5 ) {
|
||||||
auto const vehicle = pVehicles[ 0 ]; // base calculactions off relevant end of the consist
|
// porównanie modułów prędkości [km/h]
|
||||||
auto const coupler =
|
// zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej
|
||||||
vehicle->MoverParameters->Couplers + (
|
ActualProximityDist = std::min<double>(
|
||||||
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(
|
|
||||||
ActualProximityDist,
|
ActualProximityDist,
|
||||||
vehicle->fTrackBlock - (
|
Obstacle.distance );
|
||||||
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 );
|
|
||||||
|
|
||||||
if( ActualProximityDist <= (
|
if( ActualProximityDist <= (
|
||||||
( mvOccupied->CategoryFlag & 2 ) ?
|
( mvOccupied->CategoryFlag & 2 ) ?
|
||||||
100.0 : // cars
|
100.0 : // cars
|
||||||
250.0 ) ) { // others
|
250.0 ) ) { // others
|
||||||
// regardless of driving mode at close distance take precaution measures:
|
// 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
|
// match the other vehicle's speed or slow down if the other vehicle is stopped
|
||||||
VelDesired =
|
VelDesired =
|
||||||
min_speed(
|
min_speed(
|
||||||
VelDesired,
|
VelDesired,
|
||||||
std::max(
|
std::max(
|
||||||
k,
|
k,
|
||||||
( mvOccupied->CategoryFlag & 2 ) ?
|
( mvOccupied->CategoryFlag & 2 ) ?
|
||||||
40.0 : // cars
|
40.0 : // cars
|
||||||
20.0 ) ); // others
|
20.0 ) ); // others
|
||||||
if( vel > VelDesired + fVelPlus ) {
|
if( vel > VelDesired + fVelPlus ) {
|
||||||
// if going too fast force some prompt braking
|
// if going too fast force some prompt braking
|
||||||
AccPreferred = std::min( -0.65, AccPreferred );
|
AccPreferred = std::min( -0.65, AccPreferred );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double const distance = vehicle->fTrackBlock - fMaxProximityDist - ( fBrakeDist * 1.15 ); // odległość bezpieczna zależy od prędkości
|
double const distance = Obstacle.distance - fMaxProximityDist - ( fBrakeDist * 1.15 ); // odległość bezpieczna zależy od prędkości
|
||||||
if( distance < 0.0 ) {
|
if( distance < 0.0 ) {
|
||||||
// jeśli odległość jest zbyt mała
|
// jeśli odległość jest zbyt mała
|
||||||
if( k < 10.0 ) // k - prędkość tego z przodu
|
if( k < 10.0 ) // k - prędkość tego z przodu
|
||||||
{ // jeśli tamten porusza się z niewielką prędkością albo stoi
|
{ // 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 {
|
|
||||||
if( OrderCurrentGet() & Connect ) {
|
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 =
|
VelDesired =
|
||||||
min_speed(
|
min_speed(
|
||||||
VelDesired,
|
VelDesired,
|
||||||
( vehicle->fTrackBlock > 100.0 ?
|
( Obstacle.distance > 150 ?
|
||||||
20.0 :
|
20.0:
|
||||||
4.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 ) {
|
if( mvOccupied->CategoryFlag & 1 ) {
|
||||||
// trains
|
// trains
|
||||||
if( ( OrderCurrentGet() & ( Shunt | Connect ) )
|
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
|
// crude detection of edge case, if approaching another vehicle coast slowly until min distance
|
||||||
// this should allow to bunch up trainsets more on sidings
|
// this should allow to bunch up trainsets more on sidings
|
||||||
VelDesired = min_speed( 5.0, VelDesired );
|
VelDesired = min_speed( 5.0, VelDesired );
|
||||||
@@ -6344,7 +6292,7 @@ bool TController::IsStop() const
|
|||||||
double
|
double
|
||||||
TController::TrackBlock() const {
|
TController::TrackBlock() const {
|
||||||
|
|
||||||
return pVehicles[ end::front ]->fTrackBlock;
|
return Obstacle.distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TController::MoveTo(TDynamicObject *to)
|
void TController::MoveTo(TDynamicObject *to)
|
||||||
|
|||||||
1
Driver.h
1
Driver.h
@@ -376,6 +376,7 @@ private:
|
|||||||
std::size_t SemNextStopIndex{ std::size_t( -1 ) };
|
std::size_t SemNextStopIndex{ std::size_t( -1 ) };
|
||||||
double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki
|
double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki
|
||||||
basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2]
|
basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2]
|
||||||
|
neighbour_data Obstacle; // nearest vehicle detected ahead on current route
|
||||||
|
|
||||||
// timetable
|
// timetable
|
||||||
// methods
|
// 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)"
|
std::string asDestination; // dokąd pojazd ma być kierowany "(stacja):(tor)"
|
||||||
Math3D::matrix4x4 mMatrix; // macierz przekształcenia do renderowania modeli
|
Math3D::matrix4x4 mMatrix; // macierz przekształcenia do renderowania modeli
|
||||||
TMoverParameters *MoverParameters; // parametry fizyki ruchu oraz przeliczanie
|
TMoverParameters *MoverParameters; // parametry fizyki ruchu oraz przeliczanie
|
||||||
TDynamicObject *NextConnected; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
|
inline TDynamicObject *NextConnected() { return MoverParameters->Neighbours[ end::rear ].vehicle; }; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
|
||||||
TDynamicObject *PrevConnected; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
inline TDynamicObject *PrevConnected() { return MoverParameters->Neighbours[ end::front ].vehicle; }; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
||||||
int NextConnectedNo; // numer sprzęgu podłączonego z tyłu
|
inline TDynamicObject *NextConnected() const { return MoverParameters->Neighbours[ end::rear ].vehicle; }; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
|
||||||
int PrevConnectedNo; // numer sprzęgu podłączonego z przodu
|
inline TDynamicObject *PrevConnected() const { return MoverParameters->Neighbours[ end::front ].vehicle; }; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
||||||
double fScanDist; // odległość skanowania torów na obecność innych pojazdów
|
inline int NextConnectedNo() const { return MoverParameters->Neighbours[ end::rear ].vehicle_end; }
|
||||||
double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym pojazdem)
|
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;
|
TPowerSource ConnectedEnginePowerSource( TDynamicObject const *Caller ) const;
|
||||||
|
|
||||||
@@ -455,11 +456,8 @@ private:
|
|||||||
int iNumAxles; // ilość osi
|
int iNumAxles; // ilość osi
|
||||||
std::string asModel;
|
std::string asModel;
|
||||||
|
|
||||||
public:
|
|
||||||
void ABuScanObjects(int ScanDir, double ScanDist);
|
|
||||||
|
|
||||||
private:
|
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();
|
void ABuCheckMyTrack();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -470,7 +468,6 @@ private:
|
|||||||
TDynamicObject * Next();
|
TDynamicObject * Next();
|
||||||
TDynamicObject * PrevC(int C);
|
TDynamicObject * PrevC(int C);
|
||||||
TDynamicObject * NextC(int C);
|
TDynamicObject * NextC(int C);
|
||||||
double NextDistance(double d = -1.0);
|
|
||||||
void SetdMoveLen(double dMoveLen) {
|
void SetdMoveLen(double dMoveLen) {
|
||||||
MoverParameters->dMoveLen = dMoveLen; }
|
MoverParameters->dMoveLen = dMoveLen; }
|
||||||
void ResetdMoveLen() {
|
void ResetdMoveLen() {
|
||||||
@@ -485,6 +482,7 @@ private:
|
|||||||
return this ?
|
return this ?
|
||||||
asName :
|
asName :
|
||||||
std::string(); };
|
std::string(); };
|
||||||
|
std::string asBaseDir;
|
||||||
|
|
||||||
// std::ofstream PneuLogFile; //zapis parametrow pneumatycznych
|
// std::ofstream PneuLogFile; //zapis parametrow pneumatycznych
|
||||||
// youBy - dym
|
// youBy - dym
|
||||||
@@ -506,7 +504,6 @@ private:
|
|||||||
bool bDisplayCab; // czy wyswietlac kabine w train.cpp
|
bool bDisplayCab; // czy wyswietlac kabine w train.cpp
|
||||||
int iCabs; // maski bitowe modeli kabin
|
int iCabs; // maski bitowe modeli kabin
|
||||||
TTrack *MyTrack; // McZapkie-030303: tor na ktorym stoi, ABu
|
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ą
|
int iOverheadMask; // maska przydzielana przez AI pojazdom posiadającym pantograf, aby wymuszały jazdę bezprądową
|
||||||
TTractionParam tmpTraction;
|
TTractionParam tmpTraction;
|
||||||
double fAdjustment; // korekcja - docelowo przenieść do TrkFoll.cpp wraz z odległością od poprzedniego
|
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 );
|
int init_sections( TModel3d const *Model, std::string const &Nameprefix );
|
||||||
void create_controller( std::string const Type, bool const Trainset );
|
void create_controller( std::string const Type, bool const Trainset );
|
||||||
void AttachPrev(TDynamicObject *Object, int iType = 1);
|
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
|
// initiates load change by specified amounts, with a platform on specified side
|
||||||
void LoadExchange( int const Disembark, int const Embark, int const Platform );
|
void LoadExchange( int const Disembark, int const Embark, int const Platform );
|
||||||
// calculates time needed to complete current load change
|
// calculates time needed to complete current load change
|
||||||
@@ -605,14 +602,13 @@ private:
|
|||||||
Axle1.GetTranslation() :
|
Axle1.GetTranslation() :
|
||||||
Axle0.GetTranslation(); };
|
Axle0.GetTranslation(); };
|
||||||
// zwraca tor z aktywną osią
|
// zwraca tor z aktywną osią
|
||||||
inline TTrack * RaTrackGet() {
|
inline TTrack * RaTrackGet() const {
|
||||||
return iAxleFirst ?
|
return iAxleFirst ?
|
||||||
Axle1.GetTrack() :
|
Axle1.GetTrack() :
|
||||||
Axle0.GetTrack(); };
|
Axle0.GetTrack(); };
|
||||||
|
|
||||||
void couple( int const Side );
|
void couple( int const Side );
|
||||||
int uncouple( int const Side );
|
int uncouple( int const Side );
|
||||||
void CouplersDettach(double MinDist, int MyScanDir);
|
|
||||||
void RadioStop();
|
void RadioStop();
|
||||||
void Damage(char flag);
|
void Damage(char flag);
|
||||||
void RaLightsSet(int head, int rear);
|
void RaLightsSet(int head, int rear);
|
||||||
@@ -626,8 +622,11 @@ private:
|
|||||||
return iDirection + iDirection - 1; };
|
return iDirection + iDirection - 1; };
|
||||||
int DettachStatus(int dir);
|
int DettachStatus(int dir);
|
||||||
int Dettach(int dir);
|
int Dettach(int dir);
|
||||||
TDynamicObject * Neightbour(int &dir);
|
TDynamicObject * Neighbour(int &dir);
|
||||||
void CoupleDist();
|
// 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();
|
TDynamicObject * ControlledFind();
|
||||||
void ParamSet(int what, int into);
|
void ParamSet(int what, int into);
|
||||||
// zapytanie do AI, po którym segmencie skrzyżowania jechać
|
// 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
|
// vehicle sides; exclusive
|
||||||
enum end {
|
enum end {
|
||||||
front = 0,
|
front = 0,
|
||||||
rear
|
rear = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum side {
|
enum side {
|
||||||
@@ -609,18 +609,16 @@ struct power_coupling {
|
|||||||
struct TCoupling {
|
struct TCoupling {
|
||||||
/*parametry*/
|
/*parametry*/
|
||||||
double SpringKB = 1.0; /*stala sprezystosci zderzaka/sprzegu, %tlumiennosci */
|
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 DmaxB = 0.1; /*tolerancja scisku/rozciagania, sila rozerwania*/
|
||||||
double FmaxB = 1000.0;
|
double FmaxB = 1000.0;
|
||||||
|
double SpringKC = 1.0;
|
||||||
double DmaxC = 0.1;
|
double DmaxC = 0.1;
|
||||||
double FmaxC = 1000.0;
|
double FmaxC = 1000.0;
|
||||||
TCouplerType CouplerType = TCouplerType::NoCoupler; /*typ sprzegu*/
|
double beta = 0.0;
|
||||||
/*zmienne*/
|
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 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*/
|
class TMoverParameters *Connected = nullptr; /*co jest podlaczone*/
|
||||||
int ConnectedNr = 0; //Ra: od której strony podłączony do (Connected): 0=przód, 1=tył
|
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*/
|
double CForce = 0.0; /*sila z jaka dzialal*/
|
||||||
@@ -628,16 +626,25 @@ struct TCoupling {
|
|||||||
bool CheckCollision = false; /*czy sprawdzac sile czy pedy*/
|
bool CheckCollision = false; /*czy sprawdzac sile czy pedy*/
|
||||||
|
|
||||||
power_coupling power_high;
|
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
|
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
|
class TMoverParameters
|
||||||
{ // Ra: wrapper na kod pascalowy, przejmujący jego funkcje Q: 20160824 - juz nie wrapper a klasa bazowa :)
|
{ // Ra: wrapper na kod pascalowy, przejmujący jego funkcje Q: 20160824 - juz nie wrapper a klasa bazowa :)
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
|
/* TODO: implement
|
||||||
// communication cable, exchanging control signals with adjacent vehicle
|
// communication cable, exchanging control signals with adjacent vehicle
|
||||||
struct jumper_cable {
|
struct jumper_cable {
|
||||||
// types
|
// types
|
||||||
@@ -651,7 +658,7 @@ private:
|
|||||||
// integers
|
// integers
|
||||||
// std::array<int, 1> values {};
|
// std::array<int, 1> values {};
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
// basic approximation of a generic device
|
// basic approximation of a generic device
|
||||||
// TBD: inheritance or composition?
|
// TBD: inheritance or composition?
|
||||||
struct basic_device {
|
struct basic_device {
|
||||||
@@ -818,14 +825,12 @@ private:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
double dMoveLen = 0.0;
|
double dMoveLen = 0.0;
|
||||||
std::string filename;
|
|
||||||
/*---opis lokomotywy, wagonu itp*/
|
/*---opis lokomotywy, wagonu itp*/
|
||||||
/*--opis serii--*/
|
/*--opis serii--*/
|
||||||
int CategoryFlag = 1; /*1 - pociag, 2 - samochod, 4 - statek, 8 - samolot*/
|
int CategoryFlag = 1; /*1 - pociag, 2 - samochod, 4 - statek, 8 - samolot*/
|
||||||
/*--sekcja stalych typowych parametrow*/
|
/*--sekcja stalych typowych parametrow*/
|
||||||
std::string TypeName; /*nazwa serii/typu*/
|
std::string TypeName; /*nazwa serii/typu*/
|
||||||
//TrainType: string; {typ: EZT/elektrowoz - Winger 040304}
|
int TrainType = 0; /*typ: EZT/elektrowoz - Winger 040304 Ra: powinno być szybciej niż string*/
|
||||||
int TrainType = 0; /*Ra: powinno być szybciej niż string*/
|
|
||||||
TEngineType EngineType = TEngineType::None; /*typ napedu*/
|
TEngineType EngineType = TEngineType::None; /*typ napedu*/
|
||||||
TPowerParameters EnginePowerSource; /*zrodlo mocy dla silnikow*/
|
TPowerParameters EnginePowerSource; /*zrodlo mocy dla silnikow*/
|
||||||
TPowerParameters SystemPowerSource; /*zrodlo mocy dla systemow sterowania/przetwornic/sprezarek*/
|
TPowerParameters SystemPowerSource; /*zrodlo mocy dla systemow sterowania/przetwornic/sprezarek*/
|
||||||
@@ -1077,6 +1082,7 @@ public:
|
|||||||
TRotation Rot { 0.0, 0.0, 0.0 };
|
TRotation Rot { 0.0, 0.0, 0.0 };
|
||||||
std::string Name; /*nazwa wlasna*/
|
std::string Name; /*nazwa wlasna*/
|
||||||
TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami
|
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*/
|
bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/
|
||||||
int SoundFlag = 0; /*!o patrz stale sound_ */
|
int SoundFlag = 0; /*!o patrz stale sound_ */
|
||||||
double DistCounter = 0.0; /*! licznik kilometrow */
|
double DistCounter = 0.0; /*! licznik kilometrow */
|
||||||
@@ -1307,24 +1313,19 @@ public:
|
|||||||
double FrictConst2d= 0.0;
|
double FrictConst2d= 0.0;
|
||||||
double TotalMassxg = 0.0; /*TotalMass*g*/
|
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
|
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
|
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 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
|
int iLights[2]; // bity zapalonych świateł tutaj, żeby dało się liczyć pobór prądu
|
||||||
private:
|
|
||||||
double CouplerDist(int Coupler);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TMoverParameters(double VelInitial, std::string TypeNameInit, std::string NameInit, int Cab);
|
TMoverParameters(double VelInitial, std::string TypeNameInit, std::string NameInit, int Cab);
|
||||||
// obsługa sprzęgów
|
// obsługa sprzęgów
|
||||||
double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
|
static double CouplerDist( TMoverParameters const *Left, TMoverParameters const *Right );
|
||||||
/* double Distance(const vector3 &Loc1, const vector3 &Loc2, const vector3 &Dim1, const vector3 &Dim2);
|
static double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
|
||||||
*/ //bool AttachA(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced = false);
|
|
||||||
bool Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced = false, bool Audible = true);
|
bool Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced = false, bool Audible = true);
|
||||||
int DettachStatus(int ConnectNo);
|
int DettachStatus(int ConnectNo);
|
||||||
bool Dettach(int ConnectNo);
|
bool Dettach(int ConnectNo);
|
||||||
void SetCoupleDist();
|
|
||||||
bool DirectionForward();
|
bool DirectionForward();
|
||||||
void BrakeLevelSet(double b);
|
void BrakeLevelSet(double b);
|
||||||
bool BrakeLevelAdd(double b);
|
bool BrakeLevelAdd(double b);
|
||||||
@@ -1340,7 +1341,7 @@ public:
|
|||||||
|
|
||||||
// Q *******************************************************************************************
|
// Q *******************************************************************************************
|
||||||
double GetTrainsetVoltage(void);
|
double GetTrainsetVoltage(void);
|
||||||
bool Physic_ReActivation(void);
|
bool switch_physics(bool const State);
|
||||||
double LocalBrakeRatio(void);
|
double LocalBrakeRatio(void);
|
||||||
double ManualBrakeRatio(void);
|
double ManualBrakeRatio(void);
|
||||||
double PipeRatio(void);/*ile napelniac*/
|
double PipeRatio(void);/*ile napelniac*/
|
||||||
@@ -1412,17 +1413,17 @@ public:
|
|||||||
/*funkcje obliczajace sily*/
|
/*funkcje obliczajace sily*/
|
||||||
void ComputeConstans(void);//ABu: wczesniejsze wyznaczenie stalych dla liczenia sil
|
void ComputeConstans(void);//ABu: wczesniejsze wyznaczenie stalych dla liczenia sil
|
||||||
double ComputeMass(void);
|
double ComputeMass(void);
|
||||||
void ComputeTotalForce(double dt, double dt1, bool FullVer);
|
void ComputeTotalForce(double dt);
|
||||||
double Adhesive(double staticfriction) const;
|
double Adhesive(double staticfriction) const;
|
||||||
double TractionForce(double dt);
|
double TractionForce(double dt);
|
||||||
double FrictionForce(double R, int TDamage);
|
double FrictionForce(double R, int TDamage);
|
||||||
double BrakeForceR(double ratio, double velocity);
|
double BrakeForceR(double ratio, double velocity);
|
||||||
double BrakeForceP(double press, double velocity);
|
double BrakeForceP(double press, double velocity);
|
||||||
double BrakeForce(const TTrackParam &Track);
|
double BrakeForce(const TTrackParam &Track);
|
||||||
double CouplerForce(int CouplerN, double dt);
|
double CouplerForce(int const End, double dt);
|
||||||
void CollisionDetect(int CouplerN, double dt);
|
void CollisionDetect(int CouplerN, double dt);
|
||||||
/*obrot kol uwzgledniajacy poslizg*/
|
/*obrot kol uwzgledniajacy poslizg*/
|
||||||
double ComputeRotatingWheel(double WForce, double dt, double n);
|
double ComputeRotatingWheel(double WForce, double dt, double n) const;
|
||||||
|
|
||||||
/*--funkcje dla lokomotyw*/
|
/*--funkcje dla lokomotyw*/
|
||||||
bool DirectionBackward(void);/*! kierunek ruchu*/
|
bool DirectionBackward(void);/*! kierunek ruchu*/
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "MOVER.h"
|
#include "MOVER.h"
|
||||||
|
|
||||||
|
#include "DynObj.h"
|
||||||
#include "Oerlikon_ESt.h"
|
#include "Oerlikon_ESt.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
#include "Globals.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!)
|
{ // 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);
|
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)
|
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)
|
{ //łączenie do swojego sprzęgu (ConnectNo) pojazdu (ConnectTo) stroną (ConnectToNr)
|
||||||
// Ra: zwykle wykonywane dwukrotnie, dla każdego pojazdu oddzielnie
|
// 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
|
// Ra: trzeba by odróżnić wymóg dociśnięcia od uszkodzenia sprzęgu przy podczepianiu AI do składu
|
||||||
// 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
|
|
||||||
|
|
||||||
if (CouplingType == coupling::faux)
|
if( ( ConnectTo == nullptr )
|
||||||
return false; // wirtualny więcej nic nie robi
|
|| ( CouplingType == coupling::faux ) ) {
|
||||||
|
return false;
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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
|
auto const couplercheck {
|
||||||
//bool TMoverParameters::Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo,
|
( Forced )
|
||||||
// int CouplingType, bool Forced)
|
|| ( ( distance <= dEpsilon )
|
||||||
//{ //łączenie do (ConnectNo) pojazdu (ConnectTo) stroną (ConnectToNr)
|
&& ( coupler.CouplerType != TCouplerType::NoCoupler )
|
||||||
// return Attach(ConnectNo, ConnectToNr, (TMoverParameters *)ConnectTo, CouplingType, Forced);
|
&& ( 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)
|
int TMoverParameters::DettachStatus(int ConnectNo)
|
||||||
{ // Ra: sprawdzenie, czy odległość jest dobra do rozłączania
|
{ // 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ę
|
// powinny być 3 informacje: =0 sprzęg już rozłączony, <0 da się rozłączyć. >0 nie da się rozłączyć
|
||||||
// rozłączyć
|
|
||||||
if (!Couplers[ConnectNo].Connected)
|
if (!Couplers[ConnectNo].Connected)
|
||||||
return 0; // nie ma nic, to rozłączanie jest OK
|
return 0; // nie ma nic, to rozłączanie jest OK
|
||||||
if ((Couplers[ConnectNo].CouplingFlag & ctrain_coupler) == 0)
|
if ((Couplers[ConnectNo].CouplingFlag & ctrain_coupler) == 0)
|
||||||
return -Couplers[ConnectNo].CouplingFlag; // hak nie połączony - rozłączanie jest OK
|
return -Couplers[ConnectNo].CouplingFlag; // hak nie połączony - rozłączanie jest OK
|
||||||
if (TestFlag(DamageFlag, dtrain_coupling))
|
if (TestFlag(DamageFlag, dtrain_coupling))
|
||||||
return -Couplers[ConnectNo].CouplingFlag; // hak urwany - rozłączanie jest OK
|
return -Couplers[ConnectNo].CouplingFlag; // hak urwany - rozłączanie jest OK
|
||||||
// ABu021104: zakomentowane 'and (CouplerType<>Articulated)' w warunku, nie wiem co to bylo, ale
|
// CouplerDist(ConnectNo);
|
||||||
// za to teraz dziala odczepianie... :) }
|
if (Couplers[ConnectNo].CouplerType == TCouplerType::Screw ? Neighbours[ConnectNo].distance < 0.01 : true)
|
||||||
// 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)
|
|
||||||
return -Couplers[ConnectNo].CouplingFlag; // można rozłączać, jeśli dociśnięty
|
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;
|
Couplers[ConnectNo].CouplingFlag;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool TMoverParameters::Dettach(int ConnectNo)
|
bool TMoverParameters::Dettach(int ConnectNo)
|
||||||
{ // rozlaczanie
|
{ // 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
|
// set sound event flag
|
||||||
SetFlag( Couplers[ ConnectNo ].sounds, sound::detachall );
|
SetFlag( coupler.sounds, sound::detachall );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (i > 0)
|
else if (i > 0)
|
||||||
{ // odłączamy węże i resztę, pozostaje sprzęg fizyczny, który wymaga dociśnięcia (z wirtualnym
|
{ // odłączamy węże i resztę, pozostaje sprzęg fizyczny, który wymaga dociśnięcia (z wirtualnym nic)
|
||||||
// nic)
|
coupler.CouplingFlag &= coupling::coupler;
|
||||||
Couplers[ConnectNo].CouplingFlag &= ctrain_coupler;
|
othercoupler.CouplingFlag &= coupling::coupler;
|
||||||
Couplers[ConnectNo].Connected->Couplers[Couplers[ConnectNo].ConnectedNr].CouplingFlag =
|
|
||||||
Couplers[ConnectNo].CouplingFlag;
|
|
||||||
}
|
}
|
||||||
return false; // jeszcze nie rozłączony
|
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()
|
bool TMoverParameters::DirectionForward()
|
||||||
{
|
{
|
||||||
if ((MainCtrlPosNo > 0) && (ActiveDir < 1) && (MainCtrlPos == 0))
|
if ((MainCtrlPosNo > 0) && (ActiveDir < 1) && (MainCtrlPos == 0))
|
||||||
@@ -1064,7 +1015,8 @@ void TMoverParameters::CollisionDetect(int CouplerN, double dt)
|
|||||||
CCF =
|
CCF =
|
||||||
ComputeCollision(
|
ComputeCollision(
|
||||||
coupler.Connected->V,
|
coupler.Connected->V,
|
||||||
V, coupler.Connected->TotalMass,
|
V,
|
||||||
|
coupler.Connected->TotalMass,
|
||||||
TotalMass,
|
TotalMass,
|
||||||
(coupler.beta + coupler.Connected->Couplers[coupler.ConnectedNr].beta) / 2.0,
|
(coupler.beta + coupler.Connected->Couplers[coupler.ConnectedNr].beta) / 2.0,
|
||||||
VirtualCoupling)
|
VirtualCoupling)
|
||||||
@@ -3755,7 +3707,7 @@ void TMoverParameters::UpdateScndPipePressure(double dt)
|
|||||||
c = Couplers[0].Connected; // skrot
|
c = Couplers[0].Connected; // skrot
|
||||||
dv1 = 0.5 * dt * PF(ScndPipePress, c->ScndPipePress, Spz * 0.75);
|
dv1 = 0.5 * dt * PF(ScndPipePress, c->ScndPipePress, Spz * 0.75);
|
||||||
if (dv1 * dv1 > 0.00000000000001)
|
if (dv1 * dv1 > 0.00000000000001)
|
||||||
c->Physic_ReActivation();
|
c->switch_physics( true );
|
||||||
c->Pipe2->Flow(-dv1);
|
c->Pipe2->Flow(-dv1);
|
||||||
}
|
}
|
||||||
// sprzeg 2
|
// sprzeg 2
|
||||||
@@ -3765,7 +3717,7 @@ void TMoverParameters::UpdateScndPipePressure(double dt)
|
|||||||
c = Couplers[1].Connected; // skrot
|
c = Couplers[1].Connected; // skrot
|
||||||
dv2 = 0.5 * dt * PF(ScndPipePress, c->ScndPipePress, Spz * 0.75);
|
dv2 = 0.5 * dt * PF(ScndPipePress, c->ScndPipePress, Spz * 0.75);
|
||||||
if (dv2 * dv2 > 0.00000000000001)
|
if (dv2 * dv2 > 0.00000000000001)
|
||||||
c->Physic_ReActivation();
|
c->switch_physics( true );
|
||||||
c->Pipe2->Flow(-dv2);
|
c->Pipe2->Flow(-dv2);
|
||||||
}
|
}
|
||||||
if ((Couplers[1].Connected != NULL) && (Couplers[0].Connected != NULL))
|
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
|
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));
|
dv1 = 0.5 * dt * PF(PipePress, c->PipePress, (Spg) / (1.0 + 0.015 / Spg * Dim.L));
|
||||||
if (dv1 * dv1 > 0.00000000000001)
|
if (dv1 * dv1 > 0.00000000000001)
|
||||||
c->Physic_ReActivation();
|
c->switch_physics( true );
|
||||||
c->Pipe->Flow(-dv1);
|
c->Pipe->Flow(-dv1);
|
||||||
}
|
}
|
||||||
// sprzeg 2
|
// sprzeg 2
|
||||||
@@ -3826,7 +3778,7 @@ double TMoverParameters::GetDVc(double dt)
|
|||||||
c = Couplers[1].Connected; // skrot
|
c = Couplers[1].Connected; // skrot
|
||||||
dv2 = 0.5 * dt * PF(PipePress, c->PipePress, (Spg) / (1.0 + 0.015 / Spg * Dim.L));
|
dv2 = 0.5 * dt * PF(PipePress, c->PipePress, (Spg) / (1.0 + 0.015 / Spg * Dim.L));
|
||||||
if (dv2 * dv2 > 0.00000000000001)
|
if (dv2 * dv2 > 0.00000000000001)
|
||||||
c->Physic_ReActivation();
|
c->switch_physics( true );
|
||||||
c->Pipe->Flow(-dv2);
|
c->Pipe->Flow(-dv2);
|
||||||
}
|
}
|
||||||
//if ((Couplers[1].Connected != NULL) && (Couplers[0].Connected != NULL))
|
//if ((Couplers[1].Connected != NULL) && (Couplers[0].Connected != NULL))
|
||||||
@@ -3922,143 +3874,138 @@ double TMoverParameters::ComputeMass(void)
|
|||||||
// Q: 20160713
|
// Q: 20160713
|
||||||
// Obliczanie wypadkowej siły z wszystkich działających sił
|
// Obliczanie wypadkowej siły z wszystkich działających sił
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer)
|
// 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) {
|
||||||
int b;
|
|
||||||
double Fwheels = 0.0;
|
|
||||||
|
|
||||||
if (PhysicActivation)
|
Vel = std::abs(V) * 3.6; // prędkość w km/h
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// McZapkie-031103: sprawdzanie czy warto liczyc fizyke i inne updaty
|
// McZapkie-031103: sprawdzanie czy warto liczyc fizyke i inne updaty
|
||||||
// ABu 300105: cos tu mieszalem , dziala teraz troche lepiej, wiec zostawiam
|
// 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)
|
auto const vehicleisactive {
|
||||||
{
|
( CabNo != 0 )
|
||||||
if (Couplers[0].Connected != NULL)
|
|| ( Vel > 0.0001 )
|
||||||
if ((Couplers[0].Connected->Vel > 0.0001) ||
|
|| ( std::abs( AccS ) > 0.0001 )
|
||||||
(abs(Couplers[0].Connected->AccS) > 0.0001))
|
|| ( LastSwitchingTime < 5 )
|
||||||
Physic_ReActivation();
|
|| ( TrainType == dt_EZT )
|
||||||
if (Couplers[1].Connected != NULL)
|
|| ( TrainType == dt_DMU ) };
|
||||||
if ((Couplers[1].Connected->Vel > 0.0001) ||
|
|
||||||
(abs(Couplers[1].Connected->AccS) > 0.0001))
|
auto const movingvehicleahead {
|
||||||
Physic_ReActivation();
|
( Neighbours[ end::front ].vehicle != nullptr )
|
||||||
}
|
&& ( ( Neighbours[ end::front ].vehicle->MoverParameters->Vel > 0.0001 )
|
||||||
if (LastSwitchingTime > 5) // 10+Random(100) then
|
|| ( std::abs( Neighbours[ end::front ].vehicle->MoverParameters->AccS ) > 0.0001 ) ) };
|
||||||
PhysicActivation = false; // zeby nie brac pod uwage braku V po uruchomieniu programu
|
|
||||||
|
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)
|
double TMoverParameters::BrakeForceR(double ratio, double velocity)
|
||||||
@@ -4235,175 +4182,121 @@ double TMoverParameters::Adhesive(double staticfriction) const
|
|||||||
return adhesion;
|
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
|
// Q: 20160713
|
||||||
// Obliczanie sił dzialających na sprzęgach
|
// Obliczanie sił dzialających na sprzęgach
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
double TMoverParameters::CouplerForce(int CouplerN, double dt)
|
double TMoverParameters::CouplerForce( int const End, 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
|
|
||||||
|
|
||||||
Couplers[CouplerN].CheckCollision = false;
|
auto &coupler { Couplers[ End ] };
|
||||||
newdist = Couplers[CouplerN].CoupleDist; // odległość od sprzęgu sąsiada
|
auto *othervehicle { Neighbours[ End ].vehicle->MoverParameters };
|
||||||
// newdist:=Distance(Loc,Connected^.Loc,Dim,Connected^.Dim);
|
auto const otherend { Neighbours[ End ].vehicle_end };
|
||||||
if (CouplerN == 0)
|
auto &othercoupler { othervehicle->Couplers[ otherend ] };
|
||||||
{
|
|
||||||
// ABu: bylo newdist+10*((...
|
auto const othervehiclemove { ( othervehicle->dMoveLen * DirPatch( End, otherend ) ) };
|
||||||
tempdist = ((Couplers[CouplerN].Connected->dMoveLen *
|
auto const distancedelta { (
|
||||||
DirPatch(0, Couplers[CouplerN].ConnectedNr)) -
|
End == end::front ?
|
||||||
dMoveLen);
|
othervehiclemove - dMoveLen :
|
||||||
newdist += 10.0 * tempdist;
|
dMoveLen - othervehiclemove ) };
|
||||||
// tempdist:=tempdist+CoupleDist; //ABu: proby szybkiego naprawienia bledu
|
auto const initialdistance { Neighbours[ End ].distance }; // odległość od sprzęgu sąsiada
|
||||||
}
|
|
||||||
else
|
auto const newdistance =
|
||||||
{
|
initialdistance
|
||||||
// ABu: bylo newdist+10*((...
|
+ 10.0 * distancedelta;
|
||||||
tempdist = ((dMoveLen - (Couplers[CouplerN].Connected->dMoveLen *
|
|
||||||
DirPatch(1, Couplers[CouplerN].ConnectedNr))));
|
auto const dV { V - ( othervehicle->V * DirPatch( End, otherend ) ) };
|
||||||
newdist += 10.0 * tempdist;
|
auto const absdV { std::abs( dV ) };
|
||||||
// tempdist:=tempdist+CoupleDist; //ABu: proby szybkiego naprawienia bledu
|
|
||||||
}
|
|
||||||
|
|
||||||
dV = V - (double)DirPatch( CouplerN, CNext ) * Couplers[ CouplerN ].Connected->V;
|
|
||||||
absdV = abs( dV );
|
|
||||||
// potentially generate sounds on clash or stretch
|
// potentially generate sounds on clash or stretch
|
||||||
if( ( newdist < 0.0 )
|
if( ( newdistance < 0.0 )
|
||||||
&& ( Couplers[ CouplerN ].Dist > newdist )
|
&& ( coupler.Dist > newdistance )
|
||||||
&& ( dV < -0.5 ) ) {
|
&& ( dV < -0.5 ) ) {
|
||||||
// 090503: dzwieki pracy zderzakow
|
// 090503: dzwieki pracy zderzakow
|
||||||
SetFlag(
|
SetFlag(
|
||||||
Couplers[ CouplerN ].sounds,
|
coupler.sounds,
|
||||||
( absdV > 5.0 ?
|
( absdV > 5.0 ?
|
||||||
( sound::bufferclash | sound::loud ) :
|
( sound::bufferclash | sound::loud ) :
|
||||||
sound::bufferclash ) );
|
sound::bufferclash ) );
|
||||||
}
|
}
|
||||||
else if( ( Couplers[ CouplerN ].CouplingFlag != coupling::faux )
|
else if( ( coupler.CouplingFlag != coupling::faux )
|
||||||
&& ( newdist > 0.001 )
|
&& ( newdistance > 0.001 )
|
||||||
&& ( Couplers[ CouplerN ].Dist <= 0.001 )
|
&& ( coupler.Dist <= 0.001 )
|
||||||
&& ( absdV > 0.005 )
|
&& ( absdV > 0.005 )
|
||||||
&& ( Vel > 1.0 ) ) {
|
&& ( Vel > 1.0 ) ) {
|
||||||
// 090503: dzwieki pracy sprzegu
|
// 090503: dzwieki pracy sprzegu
|
||||||
SetFlag(
|
SetFlag(
|
||||||
Couplers[ CouplerN ].sounds,
|
coupler.sounds,
|
||||||
( absdV > 0.035 ?
|
( absdV > 0.035 ?
|
||||||
( sound::couplerstretch | sound::loud ) :
|
( sound::couplerstretch | sound::loud ) :
|
||||||
sound::couplerstretch ) );
|
sound::couplerstretch ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// blablabla
|
coupler.CheckCollision = false;
|
||||||
// ABu: proby znalezienia problemu ze zle odbijajacymi sie skladami
|
double CF { 0.0 };
|
||||||
//if (Couplers[CouplerN].CouplingFlag=ctrain_virtual) and (newdist>0) then
|
|
||||||
if( ( Couplers[ CouplerN ].CouplingFlag != coupling::faux )
|
|
||||||
|| ( Couplers[ CouplerN ].CoupleDist < 0 ) ) {
|
|
||||||
|
|
||||||
if( Couplers[ CouplerN ].CouplingFlag == coupling::faux ) {
|
if( ( coupler.CouplingFlag != coupling::faux )
|
||||||
|
|| ( initialdistance < 0 ) ) {
|
||||||
|
|
||||||
BetaAvg = Couplers[CouplerN].beta;
|
double BetaAvg = 0;
|
||||||
Fmax = (Couplers[CouplerN].FmaxC + Couplers[CouplerN].FmaxB) * CouplerTune;
|
double Fmax = 0;
|
||||||
|
|
||||||
|
if( coupler.CouplingFlag == coupling::faux ) {
|
||||||
|
|
||||||
|
BetaAvg = coupler.beta;
|
||||||
|
Fmax = (coupler.FmaxC + coupler.FmaxB) * CouplerTune;
|
||||||
}
|
}
|
||||||
else // usrednij bo wspolny sprzeg
|
else {
|
||||||
{
|
// usrednij bo wspolny sprzeg
|
||||||
BetaAvg =
|
BetaAvg = 0.5 * ( coupler.beta + othercoupler.beta );
|
||||||
(Couplers[CouplerN].beta + Couplers[CouplerN].Connected->Couplers[CNext].beta) /
|
Fmax = 0.5 * ( coupler.FmaxC + coupler.FmaxB + othercoupler.FmaxC + othercoupler.FmaxB ) * CouplerTune;
|
||||||
2.0;
|
|
||||||
Fmax = (Couplers[CouplerN].FmaxC + Couplers[CouplerN].FmaxB +
|
|
||||||
Couplers[CouplerN].Connected->Couplers[CNext].FmaxC +
|
|
||||||
Couplers[CouplerN].Connected->Couplers[CNext].FmaxB) *
|
|
||||||
CouplerTune / 2.0;
|
|
||||||
}
|
}
|
||||||
distDelta =
|
auto const distDelta { std::abs( newdistance ) - std::abs( coupler.Dist ) }; // McZapkie-191103: poprawka na histereze
|
||||||
abs(newdist) - abs(Couplers[CouplerN].Dist); // McZapkie-191103: poprawka na histereze
|
coupler.Dist = newdistance;
|
||||||
Couplers[CouplerN].Dist = newdist;
|
if (coupler.Dist > 0) {
|
||||||
if (Couplers[CouplerN].Dist > 0)
|
|
||||||
{
|
if( distDelta > 0 ) {
|
||||||
if (distDelta > 0)
|
CF = ( -( coupler.SpringKC + othercoupler.SpringKC ) * coupler.Dist / 2.0 ) * DirF( End )
|
||||||
CF = (-(Couplers[CouplerN].SpringKC +
|
- Fmax * dV * BetaAvg;
|
||||||
Couplers[CouplerN].Connected->Couplers[CNext].SpringKC) *
|
}
|
||||||
Couplers[CouplerN].Dist / 2.0) *
|
else {
|
||||||
DirF(CouplerN) -
|
CF = ( -( coupler.SpringKC + othercoupler.SpringKC ) * coupler.Dist / 2.0 ) * DirF( End ) * BetaAvg
|
||||||
Fmax * dV * BetaAvg;
|
- 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;
|
|
||||||
// liczenie sily ze sprezystosci sprzegu
|
// liczenie sily ze sprezystosci sprzegu
|
||||||
if (Couplers[CouplerN].Dist >
|
if( coupler.Dist > ( coupler.DmaxC + othercoupler.DmaxC ) ) {
|
||||||
(Couplers[CouplerN].DmaxC +
|
// zderzenie
|
||||||
Couplers[CouplerN].Connected->Couplers[CNext].DmaxC)) // zderzenie
|
coupler.CheckCollision = true;
|
||||||
//***if tempdist>(DmaxC+Connected^.Couplers[CNext].DmaxC) then {zderzenie}
|
}
|
||||||
Couplers[CouplerN].CheckCollision = true;
|
|
||||||
}
|
}
|
||||||
if (Couplers[CouplerN].Dist < 0)
|
if( coupler.Dist < 0 ) {
|
||||||
{
|
|
||||||
if (distDelta > 0)
|
if( distDelta > 0 ) {
|
||||||
CF = (-(Couplers[CouplerN].SpringKB +
|
CF = ( -( coupler.SpringKB + othercoupler.SpringKB ) * coupler.Dist / 2.0 ) * DirF( End )
|
||||||
Couplers[CouplerN].Connected->Couplers[CNext].SpringKB) *
|
- Fmax * dV * BetaAvg;
|
||||||
Couplers[CouplerN].Dist / 2.0) *
|
}
|
||||||
DirF(CouplerN) -
|
else {
|
||||||
Fmax * dV * BetaAvg;
|
CF = ( -( coupler.SpringKB + othercoupler.SpringKB ) * coupler.Dist / 2.0 ) * DirF( End ) * BetaAvg
|
||||||
else
|
- Fmax * dV * BetaAvg;
|
||||||
CF = (-(Couplers[CouplerN].SpringKB +
|
}
|
||||||
Couplers[CouplerN].Connected->Couplers[CNext].SpringKB) *
|
|
||||||
Couplers[CouplerN].Dist / 2.0) *
|
|
||||||
DirF(CouplerN) * BetaAvg -
|
|
||||||
Fmax * dV * BetaAvg;
|
|
||||||
// liczenie sily ze sprezystosci zderzaka
|
// liczenie sily ze sprezystosci zderzaka
|
||||||
if (-Couplers[CouplerN].Dist >
|
if( -coupler.Dist > ( coupler.DmaxB + othercoupler.DmaxB ) ) {
|
||||||
(Couplers[CouplerN].DmaxB +
|
// zderzenie
|
||||||
Couplers[CouplerN].Connected->Couplers[CNext].DmaxB)) // zderzenie
|
coupler.CheckCollision = true;
|
||||||
//***if -tempdist>(DmaxB+Connected^.Couplers[CNext].DmaxB)/10 then {zderzenie}
|
if( ( coupler.CouplerType == TCouplerType::Automatic )
|
||||||
{
|
&& ( coupler.CouplingFlag == coupling::faux ) ) {
|
||||||
Couplers[CouplerN].CheckCollision = true;
|
// sprzeganie wagonow z samoczynnymi sprzegami
|
||||||
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;
|
|
||||||
// EN57
|
// EN57
|
||||||
Couplers[ CouplerN ].CouplingFlag = coupling::coupler /*| coupling::brakehose | coupling::mainhose | coupling::control*/;
|
// TBD, TODO: configurable flag for automatic coupling
|
||||||
SetFlag( Couplers[ CouplerN ].sounds, sound::attachcoupler );
|
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
|
// uzgadnianie prawa Newtona
|
||||||
Couplers[ CouplerN ].Connected->Couplers[ 1 - CouplerN ].CForce = -CF;
|
othervehicle->Couplers[ 1 - End ].CForce = -CF;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CF;
|
return CF;
|
||||||
@@ -5314,7 +5207,7 @@ double TMoverParameters::TractionForce( double dt ) {
|
|||||||
// Q: 20160713
|
// Q: 20160713
|
||||||
//Obliczenie predkości obrotowej kół???
|
//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;
|
double newn = 0, eps = 0;
|
||||||
if ((n == 0) && (WForce * Sign(V) < 0))
|
if ((n == 0) && (WForce * Sign(V) < 0))
|
||||||
@@ -7150,17 +7043,16 @@ double TMoverParameters::GetTrainsetVoltage(void)
|
|||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
// Kasowanie zmiennych pracy fizyki
|
// 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 == State ) { return false; }
|
||||||
if (PhysicActivation)
|
|
||||||
return false;
|
PhysicActivation = State;
|
||||||
else
|
if( true == State ) {
|
||||||
{
|
|
||||||
PhysicActivation = true;
|
|
||||||
LastSwitchingTime = 0;
|
LastSwitchingTime = 0;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
@@ -9970,8 +9862,7 @@ bool TMoverParameters::RunInternalCommand()
|
|||||||
CommandIn.Location.X = 0;
|
CommandIn.Location.X = 0;
|
||||||
CommandIn.Location.Y = 0;
|
CommandIn.Location.Y = 0;
|
||||||
CommandIn.Location.Z = 0;
|
CommandIn.Location.Z = 0;
|
||||||
if (!PhysicActivation)
|
switch_physics( true );
|
||||||
Physic_ReActivation();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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( false == Train->CabChange( 1 ) ) {
|
||||||
if( TestFlag( Train->DynamicObject->MoverParameters->Couplers[ end::front ].CouplingFlag, coupling::gangway ) ) {
|
if( TestFlag( Train->DynamicObject->MoverParameters->Couplers[ end::front ].CouplingFlag, coupling::gangway ) ) {
|
||||||
// przejscie do nastepnego pojazdu
|
// przejscie do nastepnego pojazdu
|
||||||
Global.changeDynObj = Train->DynamicObject->PrevConnected;
|
Global.changeDynObj = Train->DynamicObject->PrevConnected();
|
||||||
Global.changeDynObj->MoverParameters->ActiveCab = (
|
Global.changeDynObj->MoverParameters->ActiveCab = (
|
||||||
Train->DynamicObject->PrevConnectedNo ?
|
Train->DynamicObject->MoverParameters->Neighbours[end::front].vehicle_end ?
|
||||||
-1 :
|
-1 :
|
||||||
1 );
|
1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4883,11 +4883,11 @@ void TTrain::OnCommand_cabchangebackward( TTrain *Train, command_data const &Com
|
|||||||
if( false == Train->CabChange( -1 ) ) {
|
if( false == Train->CabChange( -1 ) ) {
|
||||||
if( TestFlag( Train->DynamicObject->MoverParameters->Couplers[ end::rear ].CouplingFlag, coupling::gangway ) ) {
|
if( TestFlag( Train->DynamicObject->MoverParameters->Couplers[ end::rear ].CouplingFlag, coupling::gangway ) ) {
|
||||||
// przejscie do nastepnego pojazdu
|
// przejscie do nastepnego pojazdu
|
||||||
Global.changeDynObj = Train->DynamicObject->NextConnected;
|
Global.changeDynObj = Train->DynamicObject->NextConnected();
|
||||||
Global.changeDynObj->MoverParameters->ActiveCab = (
|
Global.changeDynObj->MoverParameters->ActiveCab = (
|
||||||
Train->DynamicObject->NextConnectedNo ?
|
Train->DynamicObject->MoverParameters->Neighbours[end::rear].vehicle_end ?
|
||||||
-1 :
|
-1 :
|
||||||
1 );
|
1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5260,14 +5260,14 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
{
|
{
|
||||||
TDynamicObject *tmp;
|
TDynamicObject *tmp;
|
||||||
tmp = NULL;
|
tmp = NULL;
|
||||||
if (DynamicObject->NextConnected)
|
if (DynamicObject->NextConnected())
|
||||||
if ((TestFlag(mvControlled->Couplers[1].CouplingFlag, ctrain_controll)) &&
|
if ((TestFlag(mvControlled->Couplers[1].CouplingFlag, ctrain_controll)) &&
|
||||||
(mvOccupied->ActiveCab == 1))
|
(mvOccupied->ActiveCab == 1))
|
||||||
tmp = DynamicObject->NextConnected;
|
tmp = DynamicObject->NextConnected();
|
||||||
if (DynamicObject->PrevConnected)
|
if (DynamicObject->PrevConnected())
|
||||||
if ((TestFlag(mvControlled->Couplers[0].CouplingFlag, ctrain_controll)) &&
|
if ((TestFlag(mvControlled->Couplers[0].CouplingFlag, ctrain_controll)) &&
|
||||||
(mvOccupied->ActiveCab == -1))
|
(mvOccupied->ActiveCab == -1))
|
||||||
tmp = DynamicObject->PrevConnected;
|
tmp = DynamicObject->PrevConnected();
|
||||||
if( tmp ) {
|
if( tmp ) {
|
||||||
if( tmp->MoverParameters->Power > 0 ) {
|
if( tmp->MoverParameters->Power > 0 ) {
|
||||||
if( ggI1B.SubModel ) {
|
if( ggI1B.SubModel ) {
|
||||||
@@ -5668,10 +5668,10 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
tmp = NULL;
|
tmp = NULL;
|
||||||
if ((TestFlag(mvControlled->Couplers[1].CouplingFlag, ctrain_controll)) &&
|
if ((TestFlag(mvControlled->Couplers[1].CouplingFlag, ctrain_controll)) &&
|
||||||
(mvOccupied->ActiveCab > 0))
|
(mvOccupied->ActiveCab > 0))
|
||||||
tmp = DynamicObject->NextConnected;
|
tmp = DynamicObject->NextConnected();
|
||||||
if ((TestFlag(mvControlled->Couplers[0].CouplingFlag, ctrain_controll)) &&
|
if ((TestFlag(mvControlled->Couplers[0].CouplingFlag, ctrain_controll)) &&
|
||||||
(mvOccupied->ActiveCab < 0))
|
(mvOccupied->ActiveCab < 0))
|
||||||
tmp = DynamicObject->PrevConnected;
|
tmp = DynamicObject->PrevConnected();
|
||||||
|
|
||||||
if (tmp)
|
if (tmp)
|
||||||
if ( mvControlled->Battery || mvControlled->ConverterFlag ) {
|
if ( mvControlled->Battery || mvControlled->ConverterFlag ) {
|
||||||
@@ -6954,26 +6954,25 @@ void TTrain::DynamicSet(TDynamicObject *d)
|
|||||||
mvOccupied = mvControlled = d ? DynamicObject->MoverParameters : NULL; // albo silnikowy w EZT
|
mvOccupied = mvControlled = d ? DynamicObject->MoverParameters : NULL; // albo silnikowy w EZT
|
||||||
if (!DynamicObject)
|
if (!DynamicObject)
|
||||||
return;
|
return;
|
||||||
if (mvControlled->TrainType & dt_EZT) // na razie dotyczy to EZT
|
// TODO: leverage code already present in TDynamicObject::ControlledFind()
|
||||||
if (DynamicObject->NextConnected ? mvControlled->Couplers[1].AllowedFlag & ctrain_depot :
|
if( ( d->MoverParameters->TrainType == dt_EZT )
|
||||||
false)
|
|| ( d->MoverParameters->TrainType == dt_DMU ) ) {
|
||||||
{ // gdy jest człon od sprzęgu 1, a sprzęg łączony
|
|
||||||
// warsztatowo (powiedzmy)
|
if( ( d->NextConnected() != nullptr )
|
||||||
if ((mvControlled->Power < 1.0) && (mvControlled->Couplers[1].Connected->Power >
|
&& ( true == TestFlag( d->MoverParameters->Couplers[ end::rear ].AllowedFlag, coupling::permanent ) ) ) {
|
||||||
1.0)) // my nie mamy mocy, ale ten drugi ma
|
if( ( mvControlled->Power < 1.0 ) && ( mvControlled->Couplers[ 1 ].Connected->Power > 1.0 ) ) {
|
||||||
mvControlled =
|
// my nie mamy mocy, ale ten drugi ma
|
||||||
DynamicObject->NextConnected->MoverParameters; // będziemy sterować tym z mocą
|
mvControlled = DynamicObject->NextConnected()->MoverParameters; // będziemy sterować tym z mocą
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (DynamicObject->PrevConnected ?
|
else if( ( d->PrevConnected() != nullptr )
|
||||||
mvControlled->Couplers[0].AllowedFlag & ctrain_depot :
|
&& ( true == TestFlag( d->MoverParameters->Couplers[ end::front ].AllowedFlag, coupling::permanent ) ) ) {
|
||||||
false)
|
if( ( mvControlled->Power < 1.0 ) && ( mvControlled->Couplers[ 0 ].Connected->Power > 1.0 ) ) {
|
||||||
{ // gdy jest człon od sprzęgu 0, a sprzęg łączony
|
// my nie mamy mocy, ale ten drugi ma
|
||||||
// warsztatowo (powiedzmy)
|
mvControlled = DynamicObject->PrevConnected()->MoverParameters; // będziemy sterować tym z mocą
|
||||||
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
|
mvSecond = NULL; // gdyby się nic nie znalazło
|
||||||
if (mvOccupied->Power > 1.0) // dwuczłonowe lub ukrotnienia, żeby nie szukać każdorazowo
|
if (mvOccupied->Power > 1.0) // dwuczłonowe lub ukrotnienia, żeby nie szukać każdorazowo
|
||||||
if (mvOccupied->Couplers[1].Connected ?
|
if (mvOccupied->Couplers[1].Connected ?
|
||||||
|
|||||||
@@ -218,8 +218,7 @@ timetable_panel::update() {
|
|||||||
auto consistmass { owner->fMass };
|
auto consistmass { owner->fMass };
|
||||||
auto consistlength { owner->fLength };
|
auto consistlength { owner->fLength };
|
||||||
if( ( owner->mvControlling->TrainType != dt_DMU )
|
if( ( owner->mvControlling->TrainType != dt_DMU )
|
||||||
&& ( owner->mvControlling->TrainType != dt_EZT )
|
&& ( owner->mvControlling->TrainType != dt_EZT ) ) {
|
||||||
&& ( owner->pVehicles[end::front] != owner->pVehicles[end::rear] ) ) {
|
|
||||||
//odejmij lokomotywy czynne, a przynajmniej aktualną
|
//odejmij lokomotywy czynne, a przynajmniej aktualną
|
||||||
consistmass -= owner->pVehicle->MoverParameters->TotalMass;
|
consistmass -= owner->pVehicle->MoverParameters->TotalMass;
|
||||||
// subtract potential other half of a two-part vehicle
|
// subtract potential other half of a two-part vehicle
|
||||||
@@ -227,7 +226,6 @@ timetable_panel::update() {
|
|||||||
if( previous != nullptr ) { consistmass -= previous->MoverParameters->TotalMass; }
|
if( previous != nullptr ) { consistmass -= previous->MoverParameters->TotalMass; }
|
||||||
auto const *next { owner->pVehicle->NextC( coupling::permanent ) };
|
auto const *next { owner->pVehicle->NextC( coupling::permanent ) };
|
||||||
if( next != nullptr ) { consistmass -= next->MoverParameters->TotalMass; }
|
if( next != nullptr ) { consistmass -= next->MoverParameters->TotalMass; }
|
||||||
// consistlength -= owner->pVehicle->MoverParameters->Dim.L;
|
|
||||||
}
|
}
|
||||||
std::snprintf(
|
std::snprintf(
|
||||||
m_buffer.data(), m_buffer.size(),
|
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
|
// NOTE: mover and vehicle are guaranteed to be valid by the caller
|
||||||
std::string couplerstatus { locale::strings[ locale::string::debug_vehicle_none ] };
|
std::string couplerstatus { locale::strings[ locale::string::debug_vehicle_none ] };
|
||||||
|
|
||||||
auto const *connected { (
|
auto const *connected { m_input.vehicle->MoverParameters->Neighbours[ Side ].vehicle };
|
||||||
Side == end::front ?
|
|
||||||
m_input.vehicle->PrevConnected :
|
|
||||||
m_input.vehicle->NextConnected ) };
|
|
||||||
|
|
||||||
if( connected == nullptr ) { return couplerstatus; }
|
if( connected == nullptr ) { return couplerstatus; }
|
||||||
|
|
||||||
@@ -574,10 +569,10 @@ debug_panel::update_vehicle_coupler( int const Side ) {
|
|||||||
|
|
||||||
std::snprintf(
|
std::snprintf(
|
||||||
m_buffer.data(), m_buffer.size(),
|
m_buffer.data(), m_buffer.size(),
|
||||||
"%s [%d]%s",
|
"%s [%d] (%.1f m)",
|
||||||
connected->name().c_str(),
|
connected->name().c_str(),
|
||||||
mover.Couplers[ Side ].CouplingFlag,
|
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() };
|
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 )
|
"Distances:\n proximity: " + to_string( mechanik.ActualProximityDist, 0 )
|
||||||
+ ", braking: " + to_string( mechanik.fBrakeDist, 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 );
|
Output.emplace_back( textline, Global.UITextColor );
|
||||||
|
|
||||||
// velocity factors
|
// velocity factors
|
||||||
|
|||||||
Reference in New Issue
Block a user