mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 23:19:19 +02:00
lpt diagnostics, tempomat configuration enhancements, ai cargo train driving logic tweaks, partial ai support for universal controller in diesel-electric vehicles
This commit is contained in:
@@ -9,6 +9,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "LPT.h"
|
#include "LPT.h"
|
||||||
|
#include "Logs.h"
|
||||||
|
|
||||||
// LPT na USB:
|
// LPT na USB:
|
||||||
// USB\VID_067B&PID_2305&REV_0200
|
// USB\VID_067B&PID_2305&REV_0200
|
||||||
@@ -24,6 +25,8 @@ OutPortType OutPort;
|
|||||||
|
|
||||||
bool TLPT::Connect(int port)
|
bool TLPT::Connect(int port)
|
||||||
{
|
{
|
||||||
|
WriteLog( "LPT: trying to access port " + std::to_string(port) );
|
||||||
|
|
||||||
// ladowanie dll-ki
|
// ladowanie dll-ki
|
||||||
hDLL = LoadLibrary("inpout32.dll");
|
hDLL = LoadLibrary("inpout32.dll");
|
||||||
if (hDLL)
|
if (hDLL)
|
||||||
@@ -32,9 +35,11 @@ bool TLPT::Connect(int port)
|
|||||||
OutPort = (OutPortType)GetProcAddress(hDLL, "Out32");
|
OutPort = (OutPortType)GetProcAddress(hDLL, "Out32");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false; // MessageBox(NULL,"ERROR","Błąd przy ładowaniu pliku",MB_OK);
|
{
|
||||||
address =
|
WriteLog("LPT: failed to load inpout32");
|
||||||
port; //&0xFFFFFC; //ostatnie 2 bity mają być zerowe -> a niech sobie OUT-ują, gdzie chcą
|
return false;
|
||||||
|
}
|
||||||
|
address = port;
|
||||||
switch (address) // nie dotyczy 0x3BC
|
switch (address) // nie dotyczy 0x3BC
|
||||||
{
|
{
|
||||||
case 0x0378:
|
case 0x0378:
|
||||||
@@ -45,6 +50,9 @@ bool TLPT::Connect(int port)
|
|||||||
case 0xBD00:
|
case 0xBD00:
|
||||||
OutPort(address + 0x006, 0); // 0xBC06? czysta improwizacja
|
OutPort(address + 0x006, 0); // 0xBC06? czysta improwizacja
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WriteLog("LPT: setup complete");
|
||||||
|
|
||||||
return OutPort != 0;
|
return OutPort != 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
122
Driver.cpp
122
Driver.cpp
@@ -153,6 +153,8 @@ const double EasyReactionTime = 0.5; //[s] przebłyski świadomości dla zwykłe
|
|||||||
const double HardReactionTime = 0.2;
|
const double HardReactionTime = 0.2;
|
||||||
const double EasyAcceleration = 0.85; //[m/ss]
|
const double EasyAcceleration = 0.85; //[m/ss]
|
||||||
const double HardAcceleration = 9.81;
|
const double HardAcceleration = 9.81;
|
||||||
|
const double CargoTrainAcceleration = 0.25;
|
||||||
|
const double HeavyCargoTrainAcceleration = 0.10;
|
||||||
const double PrepareTime = 2.0; //[s] przebłyski świadomości przy odpalaniu
|
const double PrepareTime = 2.0; //[s] przebłyski świadomości przy odpalaniu
|
||||||
bool WriteLogFlag = false;
|
bool WriteLogFlag = false;
|
||||||
double const deltalog = 0.05; // przyrost czasu
|
double const deltalog = 0.05; // przyrost czasu
|
||||||
@@ -1822,7 +1824,7 @@ void TController::OrdersClear()
|
|||||||
for (int b = 0; b < maxorders; b++)
|
for (int b = 0; b < maxorders; b++)
|
||||||
OrderList[b] = Wait_for_orders;
|
OrderList[b] = Wait_for_orders;
|
||||||
#if LOGORDERS
|
#if LOGORDERS
|
||||||
WriteLog("--> OrdersClear");
|
OrdersDump("OrdersClear", false);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2052,7 +2054,7 @@ void TController::AutoRewident()
|
|||||||
}
|
}
|
||||||
|
|
||||||
IsCargoTrain = ( mvOccupied->CategoryFlag == 1 ) && ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 );
|
IsCargoTrain = ( mvOccupied->CategoryFlag == 1 ) && ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 );
|
||||||
IsHeavyCargoTrain = ( true == IsCargoTrain ) && ( fBrake_a0[ 1 ] > 0.4 );
|
IsHeavyCargoTrain = ( true == IsCargoTrain ) && ( fBrake_a0[ 1 ] > 0.4 ) && ( iVehicles - ControlledEnginesCount > 0 ) && ( fMass / iVehicles > 50000 );
|
||||||
|
|
||||||
BrakingInitialLevel = (
|
BrakingInitialLevel = (
|
||||||
IsHeavyCargoTrain ? 1.25 :
|
IsHeavyCargoTrain ? 1.25 :
|
||||||
@@ -3176,6 +3178,10 @@ bool TController::IncSpeed()
|
|||||||
// gdy jest nakaz poczekać z jazdą, to nie ruszać
|
// gdy jest nakaz poczekać z jazdą, to nie ruszać
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if( IsAnyCouplerStretched ) {
|
||||||
|
// train is already stretched past its limits, don't pull even harder
|
||||||
|
return false;
|
||||||
|
}
|
||||||
bool OK = true;
|
bool OK = true;
|
||||||
if( ( iDrivigFlags & moveDoorOpened )
|
if( ( iDrivigFlags & moveDoorOpened )
|
||||||
&& ( VelDesired > 0.0 ) ) { // to prevent door shuffle on stop
|
&& ( VelDesired > 0.0 ) ) { // to prevent door shuffle on stop
|
||||||
@@ -3221,8 +3227,8 @@ bool TController::IncSpeed()
|
|||||||
// if the power station is heavily burdened,
|
// if the power station is heavily burdened,
|
||||||
// if it generates enough traction force
|
// if it generates enough traction force
|
||||||
// to build up speed to 30/40 km/h for passenger/cargo train (10 km/h less if going uphill)
|
// to build up speed to 30/40 km/h for passenger/cargo train (10 km/h less if going uphill)
|
||||||
auto const sufficienttractionforce { std::abs( mvControlling->Ft ) > ( IsHeavyCargoTrain ? 125 : 100 ) * 1000.0 };
|
auto const sufficienttractionforce { std::abs( mvControlling->Ft ) > ( IsHeavyCargoTrain ? 75 : 50 ) * 1000.0 };
|
||||||
auto const sufficientacceleration { AbsAccS_pub >= ( IsHeavyCargoTrain ? 0.02 : 0.04 ) };
|
auto const sufficientacceleration { AbsAccS_pub >= ( IsHeavyCargoTrain ? 0.03 : IsCargoTrain ? 0.06 : 0.09 ) };
|
||||||
auto const seriesmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 ) };
|
auto const seriesmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 ) };
|
||||||
auto const parallelmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 ) };
|
auto const parallelmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 ) };
|
||||||
auto const useseriesmodevoltage {
|
auto const useseriesmodevoltage {
|
||||||
@@ -3233,9 +3239,9 @@ bool TController::IncSpeed()
|
|||||||
auto const useseriesmode = (
|
auto const useseriesmode = (
|
||||||
( mvControlling->Imax > mvControlling->ImaxLo )
|
( mvControlling->Imax > mvControlling->ImaxLo )
|
||||||
|| ( fVoltage < useseriesmodevoltage )
|
|| ( fVoltage < useseriesmodevoltage )
|
||||||
|| ( ( true == sufficienttractionforce )
|
|| ( ( true == sufficientacceleration )
|
||||||
&& ( true == sufficientacceleration )
|
&& ( true == sufficienttractionforce )
|
||||||
&& ( mvOccupied->Vel <= ( IsCargoTrain ? 35 : 25 ) + ( seriesmodefieldshunting ? 5 : 0 ) - ( ( fAccGravity < -0.025 ) ? 10 : 0 ) ) ) );
|
&& ( mvOccupied->Vel <= ( IsCargoTrain ? 40 : 30 ) + ( seriesmodefieldshunting ? 5 : 0 ) - ( ( fAccGravity < -0.025 ) ? 10 : 0 ) ) ) );
|
||||||
// when not in series mode use the first available parallel mode configuration until 50/60 km/h for passenger/cargo train
|
// when not in series mode use the first available parallel mode configuration until 50/60 km/h for passenger/cargo train
|
||||||
// (if there's only one parallel mode configuration it'll be used regardless of current speed)
|
// (if there's only one parallel mode configuration it'll be used regardless of current speed)
|
||||||
auto const usefieldshunting = (
|
auto const usefieldshunting = (
|
||||||
@@ -3243,9 +3249,9 @@ bool TController::IncSpeed()
|
|||||||
&& ( mvControlling->RList[ mvControlling->MainCtrlPos ].R < 0.01 )
|
&& ( mvControlling->RList[ mvControlling->MainCtrlPos ].R < 0.01 )
|
||||||
&& ( useseriesmode ?
|
&& ( useseriesmode ?
|
||||||
mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 :
|
mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 :
|
||||||
( ( true == sufficienttractionforce )
|
( ( true == sufficientacceleration )
|
||||||
&& ( true == sufficientacceleration )
|
&& ( true == sufficienttractionforce )
|
||||||
&& ( mvOccupied->Vel <= ( IsCargoTrain ? 55 : 45 ) + ( parallelmodefieldshunting ? 5 : 0 ) ) ?
|
&& ( mvOccupied->Vel <= ( IsCargoTrain ? 60 : 50 ) + ( parallelmodefieldshunting ? 5 : 0 ) ) ?
|
||||||
mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 :
|
mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 :
|
||||||
mvControlling->MainCtrlPos == mvControlling->MainCtrlPosNo ) ) );
|
mvControlling->MainCtrlPos == mvControlling->MainCtrlPosNo ) ) );
|
||||||
|
|
||||||
@@ -3282,7 +3288,7 @@ bool TController::IncSpeed()
|
|||||||
mvControlling->RList[ std::min( mvControlling->MainCtrlPos + 1, mvControlling->MainCtrlPosNo ) ].Bn == 1 ?
|
mvControlling->RList[ std::min( mvControlling->MainCtrlPos + 1, mvControlling->MainCtrlPosNo ) ].Bn == 1 ?
|
||||||
mvControlling->EnginePowerSource.CollectorParameters.MinV :
|
mvControlling->EnginePowerSource.CollectorParameters.MinV :
|
||||||
useseriesmodevoltage )
|
useseriesmodevoltage )
|
||||||
> ( IsHeavyCargoTrain ? 80.0 : 60.0 ) * ControlledEnginesCount };
|
> ( IsHeavyCargoTrain ? 100.0 : 75.0 ) * ControlledEnginesCount };
|
||||||
|
|
||||||
OK = (
|
OK = (
|
||||||
( sufficientpowermargin && ( false == mvControlling->DelayCtrlFlag ) ) ?
|
( sufficientpowermargin && ( false == mvControlling->DelayCtrlFlag ) ) ?
|
||||||
@@ -3425,20 +3431,20 @@ bool TController::DecSpeed(bool force)
|
|||||||
iDrivigFlags &= ~moveIncSpeed; // usunięcie flagi jazdy
|
iDrivigFlags &= ~moveIncSpeed; // usunięcie flagi jazdy
|
||||||
if (force) // przy aktywacji kabiny jest potrzeba natychmiastowego wyzerowania
|
if (force) // przy aktywacji kabiny jest potrzeba natychmiastowego wyzerowania
|
||||||
if (mvControlling->MainCtrlPosNo > 0) // McZapkie-041003: wagon sterowniczy, np. EZT
|
if (mvControlling->MainCtrlPosNo > 0) // McZapkie-041003: wagon sterowniczy, np. EZT
|
||||||
mvControlling->DecMainCtrl((mvControlling->MainCtrlPowerPos() > 1 ? 2 : 1));
|
mvControlling->DecMainCtrl( std::min( mvControlling->MainCtrlPowerPos(), 2 ) );
|
||||||
mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania
|
mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania
|
||||||
return false;
|
return false;
|
||||||
case TEngineType::ElectricSeriesMotor:
|
case TEngineType::ElectricSeriesMotor:
|
||||||
OK = mvControlling->DecScndCtrl(2); // najpierw bocznik na zero
|
OK = mvControlling->DecScndCtrl(2); // najpierw bocznik na zero
|
||||||
if (!OK)
|
if (!OK)
|
||||||
OK = mvControlling->DecMainCtrl((mvControlling->MainCtrlPowerPos() > 1 ? 2 : 1));
|
OK = mvControlling->DecMainCtrl( std::min( mvControlling->MainCtrlPowerPos(), 2 ) );
|
||||||
mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania
|
mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania
|
||||||
break;
|
break;
|
||||||
case TEngineType::Dumb:
|
case TEngineType::Dumb:
|
||||||
case TEngineType::DieselElectric:
|
case TEngineType::DieselElectric:
|
||||||
OK = mvControlling->DecScndCtrl(2);
|
OK = mvControlling->DecScndCtrl(2);
|
||||||
if (!OK)
|
if (!OK)
|
||||||
OK = mvControlling->DecMainCtrl(2 + (mvControlling->MainCtrlPowerPos() / 2));
|
OK = mvControlling->DecMainCtrl( std::min( mvControlling->MainCtrlPowerPos(), ( 2 + (mvControlling->MainCtrlPowerPos() / 2) ) ) );
|
||||||
break;
|
break;
|
||||||
case TEngineType::ElectricInductionMotor:
|
case TEngineType::ElectricInductionMotor:
|
||||||
OK = DecSpeedEIM();
|
OK = DecSpeedEIM();
|
||||||
@@ -3515,13 +3521,13 @@ bool TController::IncSpeedEIM() {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TController::DecSpeedEIM()
|
bool TController::DecSpeedEIM( int const Amount )
|
||||||
{ // zmniejszenie prędkości (ale nie hamowanie)
|
{ // zmniejszenie prędkości (ale nie hamowanie)
|
||||||
bool OK = false; // domyślnie false, aby wyszło z pętli while
|
bool OK = false; // domyślnie false, aby wyszło z pętli while
|
||||||
switch (mvControlling->EIMCtrlType)
|
switch (mvControlling->EIMCtrlType)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
OK = mvControlling->DecMainCtrl(1);
|
OK = mvControlling->DecMainCtrl( Amount );
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
OK = mvControlling->MainCtrlPos > 4;
|
OK = mvControlling->MainCtrlPos > 4;
|
||||||
@@ -3909,6 +3915,38 @@ void TController::SetTimeControllers()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 5.5 universal control for diesel electric vehicles
|
||||||
|
if ((mvControlling->EngineType == TEngineType::DieselElectric) && (mvControlling->EIMCtrlType == 3))
|
||||||
|
{
|
||||||
|
// NOTE: partial implementation for speedinc/dec
|
||||||
|
// TBD, TODO: implement fully?
|
||||||
|
if( ( AccDesired >= 0.0 )
|
||||||
|
&& ( mvControlling->StLinFlag ) ) {
|
||||||
|
|
||||||
|
auto const PosInc { mvControlling->MainCtrlPosNo };
|
||||||
|
auto PosKeep { 0 };
|
||||||
|
auto PosDec{ 0 };
|
||||||
|
for( int i = PosInc; i >= 0; --i ) {
|
||||||
|
if( mvControlling->UniCtrlList[ i ].SetCtrlVal <= 0 ) {
|
||||||
|
if( mvControlling->UniCtrlList[ i ].SpeedDown == 0.0 ) {
|
||||||
|
PosKeep = i;
|
||||||
|
}
|
||||||
|
if( mvControlling->UniCtrlList[ i ].SpeedDown > 0.01 ) {
|
||||||
|
PosDec = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const DesiredPos { (
|
||||||
|
AccDesired > AbsAccS_pub + 0.05 ? PosInc :
|
||||||
|
AccDesired < AbsAccS_pub - 0.05 ? PosDec :
|
||||||
|
PosKeep ) };
|
||||||
|
|
||||||
|
while( ( mvControlling->MainCtrlPos > DesiredPos ) && mvControlling->DecMainCtrl( 1 ) ) { ; }
|
||||||
|
while( ( mvControlling->MainCtrlPos < DesiredPos ) && mvControlling->IncMainCtrl( 1 ) ) { ; }
|
||||||
|
}
|
||||||
|
}
|
||||||
//6. UniversalBrakeButtons
|
//6. UniversalBrakeButtons
|
||||||
//6.1. Checking flags for Over pressure
|
//6.1. Checking flags for Over pressure
|
||||||
if (std::abs(BrakeCtrlPosition - gbh_FS)<0.5) {
|
if (std::abs(BrakeCtrlPosition - gbh_FS)<0.5) {
|
||||||
@@ -4493,8 +4531,7 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
|
|||||||
OrderPos = 1;
|
OrderPos = 1;
|
||||||
}
|
}
|
||||||
#if LOGORDERS
|
#if LOGORDERS
|
||||||
WriteLog("--> Jump_to_order");
|
OrdersDump("Jump_to_order");
|
||||||
OrdersDump();
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -4658,6 +4695,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
fAccGravity = 0.0; // przyspieszenie wynikające z pochylenia
|
fAccGravity = 0.0; // przyspieszenie wynikające z pochylenia
|
||||||
double dy; // składowa styczna grawitacji, w przedziale <0,1>
|
double dy; // składowa styczna grawitacji, w przedziale <0,1>
|
||||||
double AbsAccS = 0;
|
double AbsAccS = 0;
|
||||||
|
IsAnyCouplerStretched = false;
|
||||||
IsAnyDoorOpen[ side::right ] = IsAnyDoorOpen[ side::left ] = false;
|
IsAnyDoorOpen[ side::right ] = IsAnyDoorOpen[ side::left ] = false;
|
||||||
ConsistShade = 0.0;
|
ConsistShade = 0.0;
|
||||||
TDynamicObject *p = pVehicles[0]; // pojazd na czole składu
|
TDynamicObject *p = pVehicles[0]; // pojazd na czole składu
|
||||||
@@ -4696,6 +4734,11 @@ TController::UpdateSituation(double dt) {
|
|||||||
// ciężar razy składowa styczna grawitacji
|
// ciężar razy składowa styczna grawitacji
|
||||||
fAccGravity -= vehicle->TotalMassxg * dy * ( p->DirectionGet() == iDirection ? 1 : -1 );
|
fAccGravity -= vehicle->TotalMassxg * dy * ( p->DirectionGet() == iDirection ? 1 : -1 );
|
||||||
}
|
}
|
||||||
|
// check coupler state
|
||||||
|
IsAnyCouplerStretched =
|
||||||
|
IsAnyCouplerStretched
|
||||||
|
|| ( vehicle->Couplers[ end::front ].stretch_duration > 0.0 )
|
||||||
|
|| ( vehicle->Couplers[ end::rear ].stretch_duration > 0.0 );
|
||||||
// check door state
|
// check door state
|
||||||
auto const switchsides { p->DirectionGet() != iDirection };
|
auto const switchsides { p->DirectionGet() != iDirection };
|
||||||
IsAnyDoorOpen[ side::right ] =
|
IsAnyDoorOpen[ side::right ] =
|
||||||
@@ -5385,8 +5428,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
else
|
else
|
||||||
++OrderPos;
|
++OrderPos;
|
||||||
#if LOGORDERS
|
#if LOGORDERS
|
||||||
WriteLog("--> Jump_to_first_order");
|
OrdersDump("Jump_to_first_order");
|
||||||
OrdersDump();
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case Wait_for_orders: // jeśli czeka, też ma skanować, żeby odpalić się od semafora
|
case Wait_for_orders: // jeśli czeka, też ma skanować, żeby odpalić się od semafora
|
||||||
@@ -6174,6 +6216,14 @@ TController::UpdateSituation(double dt) {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// HACK: limit acceleration for cargo trains, to reduce probability of breaking couplers on sudden jolts
|
||||||
|
// TBD: expand this behaviour to all trains with car(s) exceeding certain weight?
|
||||||
|
if( IsCargoTrain ) {
|
||||||
|
AccDesired = std::min( AccDesired, CargoTrainAcceleration );
|
||||||
|
}
|
||||||
|
if( IsHeavyCargoTrain ) {
|
||||||
|
AccDesired = std::min( AccDesired, HeavyCargoTrainAcceleration );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// for cars the older version works better
|
// for cars the older version works better
|
||||||
@@ -6283,7 +6333,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
if( vel < VelDesired ) {
|
if( vel < VelDesired ) {
|
||||||
// don't adjust acceleration when going above current goal speed
|
// don't adjust acceleration when going above current goal speed
|
||||||
if( -AccDesired * BrakeAccFactor() < (
|
if( -AccDesired * BrakeAccFactor() < (
|
||||||
( ( fReady > ( ( mvOccupied->Vel > 5.0 ) ? 0.5 : 0.4 ) )
|
( ( fReady > ( IsHeavyCargoTrain ? 0.4 : ( mvOccupied->Vel > 5.0 ) ? 0.45 : 0.4 ) )
|
||||||
|| ( VelNext > vel - 40.0 ) ) ?
|
|| ( VelNext > vel - 40.0 ) ) ?
|
||||||
fBrake_a0[ 0 ] * 0.8 :
|
fBrake_a0[ 0 ] * 0.8 :
|
||||||
-fAccThreshold )
|
-fAccThreshold )
|
||||||
@@ -6386,6 +6436,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
", VelSignal=" + AnsiString(VelSignal) + ", VelNext=" +
|
", VelSignal=" + AnsiString(VelSignal) + ", VelNext=" +
|
||||||
AnsiString(VelNext));
|
AnsiString(VelNext));
|
||||||
#endif
|
#endif
|
||||||
|
/*
|
||||||
if( ( vel < 10.0 )
|
if( ( vel < 10.0 )
|
||||||
&& ( AccDesired > 0.1 ) ) {
|
&& ( AccDesired > 0.1 ) ) {
|
||||||
// Ra 2F1H: jeśli prędkość jest mała, a można przyspieszać,
|
// Ra 2F1H: jeśli prędkość jest mała, a można przyspieszać,
|
||||||
@@ -6393,6 +6444,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
// przy małych prędkościach może być trudno utrzymać
|
// przy małych prędkościach może być trudno utrzymać
|
||||||
AccDesired = std::max( 0.9, AccDesired );
|
AccDesired = std::max( 0.9, AccDesired );
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// małe przyspieszenie
|
// małe przyspieszenie
|
||||||
// Ra 2F1I: wyłączyć kiedyś to uśrednianie i przeanalizować skanowanie, czemu migocze
|
// Ra 2F1I: wyłączyć kiedyś to uśrednianie i przeanalizować skanowanie, czemu migocze
|
||||||
if (AccDesired > -0.05) // hamowania lepeiej nie uśredniać
|
if (AccDesired > -0.05) // hamowania lepeiej nie uśredniać
|
||||||
@@ -6454,10 +6506,11 @@ TController::UpdateSituation(double dt) {
|
|||||||
else if( ( vel > VelDesired + SpeedCtrlMargin)
|
else if( ( vel > VelDesired + SpeedCtrlMargin)
|
||||||
|| ( fAccGravity < -0.01 ?
|
|| ( fAccGravity < -0.01 ?
|
||||||
AccDesired < 0.0 :
|
AccDesired < 0.0 :
|
||||||
(AbsAccS > AccDesired && AccDesired < 0.75) ) ) {
|
(AbsAccS > AccDesired + 0.05) )
|
||||||
|
|| ( IsAnyCouplerStretched ) ) {
|
||||||
// jak za bardzo przyspiesza albo prędkość przekroczona
|
// jak za bardzo przyspiesza albo prędkość przekroczona
|
||||||
// dodany wyjatek na "pelna w przod"
|
// dodany wyjatek na "pelna w przod"
|
||||||
DecSpeed(); // pojedyncze cofnięcie pozycji, bo na zero to przesada
|
DecSpeed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( mvOccupied->TrainType == dt_EZT ) {
|
if( mvOccupied->TrainType == dt_EZT ) {
|
||||||
@@ -6669,8 +6722,7 @@ void TController::JumpToNextOrder()
|
|||||||
}
|
}
|
||||||
OrderCheck();
|
OrderCheck();
|
||||||
#if LOGORDERS
|
#if LOGORDERS
|
||||||
WriteLog("--> JumpToNextOrder");
|
OrdersDump("JumpToNextOrder"); // normalnie nie ma po co tego wypisywać
|
||||||
OrdersDump(); // normalnie nie ma po co tego wypisywać
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -6681,8 +6733,7 @@ void TController::JumpToFirstOrder()
|
|||||||
OrderTop = 1;
|
OrderTop = 1;
|
||||||
OrderCheck();
|
OrderCheck();
|
||||||
#if LOGORDERS
|
#if LOGORDERS
|
||||||
WriteLog("--> JumpToFirstOrder");
|
OrdersDump("JumpToFirstOrder"); // normalnie nie ma po co tego wypisywać
|
||||||
OrdersDump(); // normalnie nie ma po co tego wypisywać
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -6733,8 +6784,7 @@ void TController::OrderNext(TOrders NewOrder)
|
|||||||
}
|
}
|
||||||
OrderList[OrderTop++] = NewOrder; // dodanie rozkazu jako następnego
|
OrderList[OrderTop++] = NewOrder; // dodanie rozkazu jako następnego
|
||||||
#if LOGORDERS
|
#if LOGORDERS
|
||||||
WriteLog("--> OrderNext");
|
OrdersDump( "OrderNext" ); // normalnie nie ma po co tego wypisywać
|
||||||
OrdersDump(); // normalnie nie ma po co tego wypisywać
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6749,17 +6799,17 @@ void TController::OrderPush(TOrders NewOrder)
|
|||||||
if (OrderTop >= maxorders)
|
if (OrderTop >= maxorders)
|
||||||
ErrorLog("Commands overflow: The program will now crash");
|
ErrorLog("Commands overflow: The program will now crash");
|
||||||
#if LOGORDERS
|
#if LOGORDERS
|
||||||
WriteLog("--> OrderPush: [" + Order2Str( NewOrder ) + "]");
|
OrdersDump( "OrderPush: [" + Order2Str( NewOrder ) + "]" ); // normalnie nie ma po co tego wypisywać
|
||||||
OrdersDump(); // normalnie nie ma po co tego wypisywać
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TController::OrdersDump()
|
void TController::OrdersDump( std::string const Neworder, bool const Verbose )
|
||||||
{ // wypisanie kolejnych rozkazów do logu
|
{ // wypisanie kolejnych rozkazów do logu
|
||||||
WriteLog("Orders for " + pVehicle->asName + ":");
|
WriteLog( "New order for [" + pVehicle->asName + "]: " + Neworder );
|
||||||
|
if( false == Verbose ) { return; }
|
||||||
for (int b = 0; b < maxorders; ++b)
|
for (int b = 0; b < maxorders; ++b)
|
||||||
{
|
{
|
||||||
WriteLog((std::to_string(b) + ": " + Order2Str(OrderList[b]) + (OrderPos == b ? " <-" : "")));
|
WriteLog( ( OrderPos == b ? ">" : " " ) + (std::to_string(b) + ": " + Order2Str(OrderList[b])));
|
||||||
if (b) // z wyjątkiem pierwszej pozycji
|
if (b) // z wyjątkiem pierwszej pozycji
|
||||||
if (OrderList[b] == Wait_for_orders) // jeśli końcowa komenda
|
if (OrderList[b] == Wait_for_orders) // jeśli końcowa komenda
|
||||||
break; // dalej nie trzeba
|
break; // dalej nie trzeba
|
||||||
@@ -6848,10 +6898,8 @@ void TController::OrdersInit(double fVel)
|
|||||||
SetVelocity(0, 0, stopSleep); // prędkość w przedziale (0;1) oznacza, że ma stać
|
SetVelocity(0, 0, stopSleep); // prędkość w przedziale (0;1) oznacza, że ma stać
|
||||||
}
|
}
|
||||||
#if LOGORDERS
|
#if LOGORDERS
|
||||||
WriteLog("--> OrdersInit");
|
OrdersDump( "OrdersInit", DebugModeFlag ); // wypisanie kontrolne tabelki rozkazów
|
||||||
#endif
|
#endif
|
||||||
if (DebugModeFlag) // normalnie nie ma po co tego wypisywać
|
|
||||||
OrdersDump(); // wypisanie kontrolne tabelki rozkazów
|
|
||||||
// McZapkie! - zeby w ogole AI ruszyl to musi wykonac powyzsze rozkazy
|
// McZapkie! - zeby w ogole AI ruszyl to musi wykonac powyzsze rozkazy
|
||||||
// Ale mozna by je zapodac ze scenerii
|
// Ale mozna by je zapodac ze scenerii
|
||||||
};
|
};
|
||||||
|
|||||||
5
Driver.h
5
Driver.h
@@ -240,7 +240,7 @@ private:
|
|||||||
bool IncBrakeEIM();
|
bool IncBrakeEIM();
|
||||||
bool DecBrakeEIM();
|
bool DecBrakeEIM();
|
||||||
bool IncSpeedEIM();
|
bool IncSpeedEIM();
|
||||||
bool DecSpeedEIM();
|
bool DecSpeedEIM( int const Amount = 1 );
|
||||||
void BrakeLevelSet( double b );
|
void BrakeLevelSet( double b );
|
||||||
bool BrakeLevelAdd( double b );
|
bool BrakeLevelAdd( double b );
|
||||||
void SpeedSet();
|
void SpeedSet();
|
||||||
@@ -370,7 +370,7 @@ private:
|
|||||||
void OrderCheck();
|
void OrderCheck();
|
||||||
void OrdersInit( double fVel );
|
void OrdersInit( double fVel );
|
||||||
void OrdersClear();
|
void OrdersClear();
|
||||||
void OrdersDump();
|
void OrdersDump( std::string const Neworder, bool const Verbose = true );
|
||||||
std::string Order2Str( TOrders Order ) const;
|
std::string Order2Str( TOrders Order ) const;
|
||||||
// members
|
// members
|
||||||
std::string m_assignment;
|
std::string m_assignment;
|
||||||
@@ -484,6 +484,7 @@ private:
|
|||||||
bool IsAnyMotorOverloadRelayOpen{ false }; // state of motor overload relays in all vehicles under control
|
bool IsAnyMotorOverloadRelayOpen{ false }; // state of motor overload relays in all vehicles under control
|
||||||
bool IsAnyGroundRelayOpen{ false };
|
bool IsAnyGroundRelayOpen{ false };
|
||||||
bool IsAnyCompressorEnabled{ false };
|
bool IsAnyCompressorEnabled{ false };
|
||||||
|
bool IsAnyCouplerStretched{ false }; // whether there's a coupler in the consist stretched above limit
|
||||||
|
|
||||||
// logs
|
// logs
|
||||||
// methods
|
// methods
|
||||||
|
|||||||
50
DynObj.cpp
50
DynObj.cpp
@@ -1552,7 +1552,7 @@ TDynamicObject::uncouple( int const Side ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TDynamicObject::attach_coupler_adapter( int const Side ) {
|
TDynamicObject::attach_coupler_adapter( int const Side, bool const Enforce ) {
|
||||||
|
|
||||||
auto &coupler { MoverParameters->Couplers[ Side ] };
|
auto &coupler { MoverParameters->Couplers[ Side ] };
|
||||||
// sanity check(s)
|
// sanity check(s)
|
||||||
@@ -1572,7 +1572,8 @@ TDynamicObject::attach_coupler_adapter( int const Side ) {
|
|||||||
// explicit coupler adapter definition overrides default parameters
|
// explicit coupler adapter definition overrides default parameters
|
||||||
adapterdata = neighbour->m_coupleradapter;
|
adapterdata = neighbour->m_coupleradapter;
|
||||||
}
|
}
|
||||||
if( MoverParameters->Neighbours[ Side ].distance - adapterdata.position.x < 0.5 ) {
|
if( ( MoverParameters->Neighbours[ Side ].distance - adapterdata.position.x < 0.5 )
|
||||||
|
&& ( false == Enforce ) ) {
|
||||||
// arbitrary amount of free room required to install the adapter
|
// arbitrary amount of free room required to install the adapter
|
||||||
// NOTE: this also covers cases with established physical connection
|
// NOTE: this also covers cases with established physical connection
|
||||||
return false;
|
return false;
|
||||||
@@ -2483,13 +2484,51 @@ void TDynamicObject::Move(double fDistance)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void TDynamicObject::AttachPrev(TDynamicObject *Object, int iType)
|
void TDynamicObject::AttachNext(TDynamicObject *Object, int iType)
|
||||||
{ // Ra: doczepia Object na końcu składu (nazwa funkcji może być myląca)
|
{ // Ra: doczepia Object na końcu składu (nazwa funkcji może być myląca)
|
||||||
// Ra: używane tylko przy wczytywaniu scenerii
|
// Ra: używane tylko przy wczytywaniu scenerii
|
||||||
MoverParameters->Attach( iDirection, Object->iDirection ^ 1, Object->MoverParameters, iType, true, false );
|
auto const vehicleend { iDirection };
|
||||||
|
auto const othervehicleend { Object->iDirection ^ 1 };
|
||||||
|
|
||||||
|
MoverParameters->Attach( vehicleend, othervehicleend, Object->MoverParameters, iType, true, false );
|
||||||
// update neighbour data for both affected vehicles
|
// update neighbour data for both affected vehicles
|
||||||
update_neighbours();
|
update_neighbours();
|
||||||
Object->update_neighbours();
|
Object->update_neighbours();
|
||||||
|
|
||||||
|
// potentially attach automatic coupler adapter to allow the connection
|
||||||
|
// HACK: we're doing it after establishin actual connection, as the method needs valid neighbour data
|
||||||
|
auto &coupler { MoverParameters->Couplers[ vehicleend ] };
|
||||||
|
auto &othercoupler { Object->MoverParameters->Couplers[ ( othervehicleend != 2 ? othervehicleend : coupler.ConnectedNr ) ] };
|
||||||
|
|
||||||
|
if( coupler.type() != othercoupler.type() ) {
|
||||||
|
if( othercoupler.type() == TCouplerType::Automatic ) {
|
||||||
|
// try to attach adapter to the vehicle
|
||||||
|
attach_coupler_adapter(
|
||||||
|
vehicleend,
|
||||||
|
true );
|
||||||
|
}
|
||||||
|
else if( coupler.type() == TCouplerType::Automatic ) {
|
||||||
|
// try to attach adapter to the other vehicle
|
||||||
|
Object->attach_coupler_adapter(
|
||||||
|
( othervehicleend != 2 ? othervehicleend : coupler.ConnectedNr ),
|
||||||
|
true );
|
||||||
|
}
|
||||||
|
// update distance to neighbours on account of potentially attached adapter
|
||||||
|
update_neighbours();
|
||||||
|
Object->update_neighbours();
|
||||||
|
}
|
||||||
|
// potentially adjust vehicle position to avoid collision at the simulation start
|
||||||
|
if( MoverParameters->Neighbours[ vehicleend ].distance > -0.001 ) { return; }
|
||||||
|
|
||||||
|
Object->Move( MoverParameters->Neighbours[ vehicleend ].distance * Object->DirectionGet() );
|
||||||
|
// HACK: manually update vehicle position as it's used by neighbour distance update we do next
|
||||||
|
Object->MoverParameters->Loc = {
|
||||||
|
-Object->vPosition.x,
|
||||||
|
Object->vPosition.z,
|
||||||
|
Object->vPosition.y };
|
||||||
|
// update neighbour distance data after moving our vehicle
|
||||||
|
update_neighbours();
|
||||||
|
Object->update_neighbours();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TDynamicObject::UpdateForce(double dt)
|
bool TDynamicObject::UpdateForce(double dt)
|
||||||
@@ -3063,7 +3102,8 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
if (((MoverParameters->ShuntMode) && (Frj < 0.0015 * masa)) ||
|
if (((MoverParameters->ShuntMode) && (Frj < 0.0015 * masa)) ||
|
||||||
(MoverParameters->V * MoverParameters->DirAbsolute < -0.2))
|
(MoverParameters->V * MoverParameters->DirAbsolute < -0.2))
|
||||||
{
|
{
|
||||||
Fzad = std::max(MoverParameters->StopBrakeDecc * masa, Fzad);
|
auto const sbd { ( ( MoverParameters->SpringBrake.IsActive && MoverParameters->ReleaseParkingBySpringBrake ) ? 0.0 : MoverParameters->StopBrakeDecc ) };
|
||||||
|
Fzad = std::max( Fzad, sbd * masa );
|
||||||
}
|
}
|
||||||
if ((Fzad > 1) && (!MEDLogFile.is_open()) && (MoverParameters->Vel > 1))
|
if ((Fzad > 1) && (!MEDLogFile.is_open()) && (MoverParameters->Vel > 1))
|
||||||
{
|
{
|
||||||
|
|||||||
4
DynObj.h
4
DynObj.h
@@ -564,7 +564,7 @@ private:
|
|||||||
int init_sections( TModel3d const *Model, std::string const &Nameprefix, bool const Overrideselfillum );
|
int init_sections( TModel3d const *Model, std::string const &Nameprefix, bool const Overrideselfillum );
|
||||||
bool init_destination( TModel3d *Model );
|
bool init_destination( TModel3d *Model );
|
||||||
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 AttachNext(TDynamicObject *Object, int iType = 1);
|
||||||
bool UpdateForce(double dt);
|
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 );
|
||||||
@@ -660,7 +660,7 @@ private:
|
|||||||
|
|
||||||
void couple( int const Side );
|
void couple( int const Side );
|
||||||
int uncouple( int const Side );
|
int uncouple( int const Side );
|
||||||
bool attach_coupler_adapter( int const Side );
|
bool attach_coupler_adapter( int const Side, bool const Enforce = false );
|
||||||
bool remove_coupler_adapter( int const Side );
|
bool remove_coupler_adapter( int const Side );
|
||||||
void RadioStop();
|
void RadioStop();
|
||||||
void Damage(char flag);
|
void Damage(char flag);
|
||||||
|
|||||||
@@ -121,12 +121,12 @@ static int const dtrain_axle = 64;
|
|||||||
static int const dtrain_out = 128; /*wykolejenie*/
|
static int const dtrain_out = 128; /*wykolejenie*/
|
||||||
|
|
||||||
/*wagi prawdopodobienstwa dla funkcji FuzzyLogic*/
|
/*wagi prawdopodobienstwa dla funkcji FuzzyLogic*/
|
||||||
#define p_elengproblem (1.000000E-02)
|
#define p_elengproblem (1e-02)
|
||||||
#define p_elengdamage (1.000000E-01)
|
#define p_elengdamage (1e-01)
|
||||||
#define p_coupldmg (2.000000E-02)
|
#define p_coupldmg (2e-03)
|
||||||
#define p_derail (1.000000E-03)
|
#define p_derail (1e-03)
|
||||||
#define p_accn (1.000000E-01)
|
#define p_accn (1e-01)
|
||||||
#define p_slippdmg (1.000000E-03)
|
#define p_slippdmg (1e-03)
|
||||||
|
|
||||||
/*typ sprzegu*/
|
/*typ sprzegu*/
|
||||||
static int const ctrain_virtual = 0; //gdy pojazdy na tym samym torze się widzą wzajemnie
|
static int const ctrain_virtual = 0; //gdy pojazdy na tym samym torze się widzą wzajemnie
|
||||||
@@ -759,6 +759,8 @@ struct speed_control {
|
|||||||
double FactorIpos = 0.0;
|
double FactorIpos = 0.0;
|
||||||
double FactorIneg = 0.0;
|
double FactorIneg = 0.0;
|
||||||
double BrakeInterventionVel = 30.0;
|
double BrakeInterventionVel = 30.0;
|
||||||
|
double PowerUpSpeed = 1000;
|
||||||
|
double PowerDownSpeed = 1000;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TMoverParameters
|
class TMoverParameters
|
||||||
@@ -1127,6 +1129,7 @@ public:
|
|||||||
int ScndInMain{ 0 }; /*zaleznosc bocznika od nastawnika*/
|
int ScndInMain{ 0 }; /*zaleznosc bocznika od nastawnika*/
|
||||||
bool MBrake = false; /*Czy jest hamulec reczny*/
|
bool MBrake = false; /*Czy jest hamulec reczny*/
|
||||||
double StopBrakeDecc = 0.0;
|
double StopBrakeDecc = 0.0;
|
||||||
|
bool ReleaseParkingBySpringBrake { false };
|
||||||
TSecuritySystem SecuritySystem;
|
TSecuritySystem SecuritySystem;
|
||||||
int EmergencyBrakeWarningSignal{ 0 }; // combined with basic WarningSignal when manual emergency brake is active
|
int EmergencyBrakeWarningSignal{ 0 }; // combined with basic WarningSignal when manual emergency brake is active
|
||||||
TUniversalCtrlTable UniCtrlList; /*lista pozycji uniwersalnego nastawnika*/
|
TUniversalCtrlTable UniCtrlList; /*lista pozycji uniwersalnego nastawnika*/
|
||||||
@@ -1602,7 +1605,7 @@ public:
|
|||||||
// obsługa sprzęgów
|
// obsługa sprzęgów
|
||||||
static double CouplerDist( TMoverParameters const *Left, TMoverParameters const *Right );
|
static double CouplerDist( TMoverParameters const *Left, TMoverParameters const *Right );
|
||||||
static double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
|
static double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
|
||||||
bool Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced = false, bool Audible = true);
|
bool Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Enforce = false, bool Audible = true);
|
||||||
int DettachStatus(int ConnectNo);
|
int DettachStatus(int ConnectNo);
|
||||||
bool Dettach(int ConnectNo);
|
bool Dettach(int ConnectNo);
|
||||||
void damage_coupler( int const End );
|
void damage_coupler( int const End );
|
||||||
@@ -1645,8 +1648,8 @@ public:
|
|||||||
bool RunCommand( std::string Command, double CValue1, double CValue2, int const Couplertype = ctrain_controll );
|
bool RunCommand( std::string Command, double CValue1, double CValue2, int const Couplertype = ctrain_controll );
|
||||||
bool RunInternalCommand();
|
bool RunInternalCommand();
|
||||||
void PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation);
|
void PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation);
|
||||||
bool CabActivisation( bool const Force = false );
|
bool CabActivisation( bool const Enforce = false );
|
||||||
bool CabDeactivisation( bool const Force = false );
|
bool CabDeactivisation( bool const Enforce = false );
|
||||||
|
|
||||||
/*! funkcje zwiekszajace/zmniejszajace nastawniki*/
|
/*! funkcje zwiekszajace/zmniejszajace nastawniki*/
|
||||||
/*! glowny nastawnik:*/
|
/*! glowny nastawnik:*/
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
#include "simulation.h"
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Ra: tu należy przenosić funcje z mover.pas, które nie są z niego wywoływane.
|
// Ra: tu należy przenosić funcje z mover.pas, które nie są z niego wywoływane.
|
||||||
@@ -426,7 +427,7 @@ double TMoverParameters::CouplerDist(TMoverParameters const *Left, TMoverParamet
|
|||||||
Left->Dim, Right->Dim); // odległość pomiędzy sprzęgami (kula!)
|
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 Enforce, 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 składu
|
// Ra: trzeba by odróżnić wymóg dociśnięcia od uszkodzenia sprzęgu przy podczepianiu AI do składu
|
||||||
@@ -441,7 +442,7 @@ bool TMoverParameters::Attach(int ConnectNo, int ConnectToNr, TMoverParameters *
|
|||||||
auto const distance { CouplerDist( this, ConnectTo ) - ( coupler.adapter_length + othercoupler.adapter_length ) };
|
auto const distance { CouplerDist( this, ConnectTo ) - ( coupler.adapter_length + othercoupler.adapter_length ) };
|
||||||
|
|
||||||
auto const couplercheck {
|
auto const couplercheck {
|
||||||
( Forced )
|
( Enforce )
|
||||||
|| ( ( distance <= dEpsilon )
|
|| ( ( distance <= dEpsilon )
|
||||||
&& ( coupler.type() != TCouplerType::NoCoupler )
|
&& ( coupler.type() != TCouplerType::NoCoupler )
|
||||||
&& ( coupler.type() == othercoupler.type() ) ) };
|
&& ( coupler.type() == othercoupler.type() ) ) };
|
||||||
@@ -1044,12 +1045,14 @@ void TMoverParameters::CollisionDetect(int const End, double const dt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( coupler.Dist < 0 )
|
if( ( -coupler.Dist >= coupler.DmaxB )
|
||||||
&& ( FuzzyLogic( std::abs( CCF ), 5.0 * ( coupler.FmaxC + 1.0 ), p_coupldmg ) ) ) {
|
&& ( FuzzyLogic( std::abs( CCF ), 5.0 * ( coupler.FmaxC + 1.0 ), p_coupldmg ) ) ) {
|
||||||
// small chance to smash the coupler if it's hit with excessive force
|
// small chance to smash the coupler if it's hit with excessive force
|
||||||
damage_coupler( End );
|
damage_coupler( End );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( ( coupler.CouplingFlag == coupling::faux
|
||||||
|
|| ( true == TestFlag( othervehicle->DamageFlag, dtrain_out ) ) ) ) { // HACK: limit excessive speed derailment checks to vehicles which aren't part of the same consist
|
||||||
auto const safevelocitylimit { 15.0 };
|
auto const safevelocitylimit { 15.0 };
|
||||||
auto const velocitydifference {
|
auto const velocitydifference {
|
||||||
glm::length(
|
glm::length(
|
||||||
@@ -1071,6 +1074,7 @@ void TMoverParameters::CollisionDetect(int const End, double const dt)
|
|||||||
othervehicle->derail( 5 );
|
othervehicle->derail( 5 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// adjust velocity and acceleration of affected vehicles
|
// adjust velocity and acceleration of affected vehicles
|
||||||
if( false == TestFlag( DamageFlag, dtrain_out ) ) {
|
if( false == TestFlag( DamageFlag, dtrain_out ) ) {
|
||||||
@@ -2291,6 +2295,9 @@ bool TMoverParameters::DecMainCtrl(int CtrlSpeed)
|
|||||||
// nie ma sterowania
|
// nie ma sterowania
|
||||||
OK = false;
|
OK = false;
|
||||||
}
|
}
|
||||||
|
else if( CtrlSpeed == 0 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TBD, TODO: replace with mainctrlpowerpos() check?
|
// TBD, TODO: replace with mainctrlpowerpos() check?
|
||||||
@@ -2324,7 +2331,7 @@ bool TMoverParameters::DecMainCtrl(int CtrlSpeed)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (CtrlSpeed > 1)
|
else if (CtrlSpeed > 1)
|
||||||
OK = (DecMainCtrl(1) && DecMainCtrl(2)); // CtrlSpeed-1);
|
OK = (DecMainCtrl(1) && DecMainCtrl(CtrlSpeed - 1)); // CtrlSpeed-1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2569,11 +2576,11 @@ bool TMoverParameters::DecScndCtrl(int CtrlSpeed)
|
|||||||
// Q: 20160710
|
// Q: 20160710
|
||||||
// załączenie rozrządu
|
// załączenie rozrządu
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
bool TMoverParameters::CabActivisation( bool const Force )
|
bool TMoverParameters::CabActivisation( bool const Enforce )
|
||||||
{
|
{
|
||||||
bool OK = false;
|
bool OK = false;
|
||||||
|
|
||||||
OK = Force || (CabActive == 0); // numer kabiny, z której jest sterowanie
|
OK = Enforce || (CabActive == 0); // numer kabiny, z której jest sterowanie
|
||||||
if (OK)
|
if (OK)
|
||||||
{
|
{
|
||||||
CabActive = CabOccupied; // sterowanie jest z kabiny z obsadą
|
CabActive = CabOccupied; // sterowanie jest z kabiny z obsadą
|
||||||
@@ -2588,11 +2595,11 @@ bool TMoverParameters::CabActivisation( bool const Force )
|
|||||||
// Q: 20160710
|
// Q: 20160710
|
||||||
// wyłączenie rozrządu
|
// wyłączenie rozrządu
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
bool TMoverParameters::CabDeactivisation( bool const Force )
|
bool TMoverParameters::CabDeactivisation( bool const Enforce )
|
||||||
{
|
{
|
||||||
bool OK = false;
|
bool OK = false;
|
||||||
|
|
||||||
OK = Force || (CabActive == CabOccupied); // o ile obsada jest w kabinie ze sterowaniem
|
OK = Enforce || (CabActive == CabOccupied); // o ile obsada jest w kabinie ze sterowaniem
|
||||||
if (OK)
|
if (OK)
|
||||||
{
|
{
|
||||||
CabActive = 0;
|
CabActive = 0;
|
||||||
@@ -7065,6 +7072,7 @@ void TMoverParameters::CheckSpeedCtrl(double dt)
|
|||||||
}
|
}
|
||||||
if ((EIMCtrlType >= 3)&&(UniCtrlList[MainCtrlPos].SpeedUp <= 0)) {
|
if ((EIMCtrlType >= 3)&&(UniCtrlList[MainCtrlPos].SpeedUp <= 0)) {
|
||||||
accfactor = 0.0;
|
accfactor = 0.0;
|
||||||
|
eimicSpeedCtrl = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SpeedCtrlUnit.IsActive) {//speed control
|
if (SpeedCtrlUnit.IsActive) {//speed control
|
||||||
@@ -7079,7 +7087,7 @@ void TMoverParameters::CheckSpeedCtrl(double dt)
|
|||||||
bool retarder_not_work = (EngineType != TEngineType::DieselEngine) || (Vel < SpeedCtrlUnit.BrakeInterventionVel);
|
bool retarder_not_work = (EngineType != TEngineType::DieselEngine) || (Vel < SpeedCtrlUnit.BrakeInterventionVel);
|
||||||
if (eSCP < -1.0)
|
if (eSCP < -1.0)
|
||||||
{
|
{
|
||||||
SpeedCtrlUnit.BrakeInterventionBraking = (eSCP < -1.1) && retarder_not_work;
|
SpeedCtrlUnit.BrakeInterventionBraking = (eSCP < -1.1) && retarder_not_work && (eimicSpeedCtrl < -0.99 * SpeedCtrlUnit.DesiredPower);
|
||||||
eSCP = -1.0;
|
eSCP = -1.0;
|
||||||
}
|
}
|
||||||
SpeedCtrlUnit.BrakeInterventionUnbraking = (eSCP > 0.0) || (Vel == 0.0);
|
SpeedCtrlUnit.BrakeInterventionUnbraking = (eSCP > 0.0) || (Vel == 0.0);
|
||||||
@@ -7092,7 +7100,11 @@ void TMoverParameters::CheckSpeedCtrl(double dt)
|
|||||||
else {
|
else {
|
||||||
eimicSpeedCtrlIntegral = 0;
|
eimicSpeedCtrlIntegral = 0;
|
||||||
}
|
}
|
||||||
eimicSpeedCtrl = clamp(eimicSpeedCtrlIntegral + eSCP, -SpeedCtrlUnit.DesiredPower, accfactor);
|
auto const DesiredeimicSpeedCtrl { clamp( eimicSpeedCtrlIntegral + eSCP, -SpeedCtrlUnit.DesiredPower, accfactor ) };
|
||||||
|
eimicSpeedCtrl = clamp(
|
||||||
|
DesiredeimicSpeedCtrl,
|
||||||
|
eimicSpeedCtrl - SpeedCtrlUnit.PowerDownSpeed * dt,
|
||||||
|
eimicSpeedCtrl + SpeedCtrlUnit.PowerUpSpeed * dt );
|
||||||
if (Vel < SpeedCtrlUnit.FullPowerVelocity) {
|
if (Vel < SpeedCtrlUnit.FullPowerVelocity) {
|
||||||
eimicSpeedCtrl = std::min(eimicSpeedCtrl, SpeedCtrlUnit.InitialPower);
|
eimicSpeedCtrl = std::min(eimicSpeedCtrl, SpeedCtrlUnit.InitialPower);
|
||||||
}
|
}
|
||||||
@@ -10090,6 +10102,7 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
|
|||||||
0;
|
0;
|
||||||
|
|
||||||
extract_value( StopBrakeDecc, "SBD", line, "" );
|
extract_value( StopBrakeDecc, "SBD", line, "" );
|
||||||
|
extract_value( ReleaseParkingBySpringBrake, "ReleaseParkingBySpringBrake", line, "" );
|
||||||
|
|
||||||
std::map<std::string, start_t> starts {
|
std::map<std::string, start_t> starts {
|
||||||
{ "Disabled", start_t::disabled },
|
{ "Disabled", start_t::disabled },
|
||||||
@@ -10368,8 +10381,8 @@ void TMoverParameters::LoadFIZ_SpeedControl(std::string const &Line) {
|
|||||||
extract_value(SpeedCtrlUnit.FactorIpos, "kIpos", Line, "");
|
extract_value(SpeedCtrlUnit.FactorIpos, "kIpos", Line, "");
|
||||||
extract_value(SpeedCtrlUnit.FactorIneg, "kIneg", Line, "");
|
extract_value(SpeedCtrlUnit.FactorIneg, "kIneg", Line, "");
|
||||||
extract_value(SpeedCtrlUnit.BrakeInterventionVel, "BrakeIntMaxVel", Line, "");
|
extract_value(SpeedCtrlUnit.BrakeInterventionVel, "BrakeIntMaxVel", Line, "");
|
||||||
|
extract_value(SpeedCtrlUnit.PowerUpSpeed, "PowerUpSpeed", Line, "" );
|
||||||
|
extract_value(SpeedCtrlUnit.PowerDownSpeed, "PowerDownSpeed", Line, "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ auto python_taskqueue::init() -> bool {
|
|||||||
// release the lock, save the state for future use
|
// release the lock, save the state for future use
|
||||||
m_mainthread = PyEval_SaveThread();
|
m_mainthread = PyEval_SaveThread();
|
||||||
|
|
||||||
WriteLog( "Python Interpreter setup complete" );
|
WriteLog( "Python Interpreter: setup complete" );
|
||||||
|
|
||||||
// init workers
|
// init workers
|
||||||
for( auto &worker : m_workers ) {
|
for( auto &worker : m_workers ) {
|
||||||
|
|||||||
@@ -689,7 +689,7 @@ state_serializer::deserialize_endtrainset( cParser &Input, scene::scratch_data &
|
|||||||
}
|
}
|
||||||
if( vehicleindex > 0 ) {
|
if( vehicleindex > 0 ) {
|
||||||
// from second vehicle on couple it with the previous one
|
// from second vehicle on couple it with the previous one
|
||||||
Scratchpad.trainset.vehicles[ vehicleindex - 1 ]->AttachPrev(
|
Scratchpad.trainset.vehicles[ vehicleindex - 1 ]->AttachNext(
|
||||||
vehicle,
|
vehicle,
|
||||||
Scratchpad.trainset.couplings[ vehicleindex - 1 ] );
|
Scratchpad.trainset.couplings[ vehicleindex - 1 ] );
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user