mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 12:09:18 +02:00
build 190902. vehicle derailment, oil pressure change tweak, inverter sound tweak, car braking logic tweak, flashing alerter ui indicator, departure signal sources reduction, additional train state data exposed to uart interface, additional train state data for python scripts, wind simulation tweak, coupler animation fix
This commit is contained in:
13
Driver.cpp
13
Driver.cpp
@@ -1138,6 +1138,17 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
if( sSpeedTable[ i ].fDist > 0.0 ) {
|
if( sSpeedTable[ i ].fDist > 0.0 ) {
|
||||||
// check signals ahead
|
// check signals ahead
|
||||||
if( sSpeedTable[ i ].IsProperSemaphor( OrderCurrentGet() ) ) {
|
if( sSpeedTable[ i ].IsProperSemaphor( OrderCurrentGet() ) ) {
|
||||||
|
|
||||||
|
if( ( mvOccupied->CategoryFlag & 2 )
|
||||||
|
&& ( sSpeedTable[ i ].fVelNext != -1.0 )
|
||||||
|
&& ( sSpeedTable[ i ].fVelNext < 1.0 )
|
||||||
|
&& ( sSpeedTable[ i ].fDist < -0.5 + std::min( fBrakeDist * 0.2, mvOccupied->Vel * 0.2 ) ) ) {
|
||||||
|
// special rule for cars: ignore stop signals at distance too short to come to a stop
|
||||||
|
// as trying to stop in such situation is likely to place the car on train tracks
|
||||||
|
sSpeedTable[ i ].iFlags &= ~spEnabled;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if( SemNextIndex == -1 ) {
|
if( SemNextIndex == -1 ) {
|
||||||
// jeśli jest mienięty poprzedni semafor a wcześniej
|
// jeśli jest mienięty poprzedni semafor a wcześniej
|
||||||
// byl nowy to go dorzucamy do zmiennej, żeby cały czas widział najbliższy
|
// byl nowy to go dorzucamy do zmiennej, żeby cały czas widział najbliższy
|
||||||
@@ -5907,7 +5918,7 @@ TController::UpdateSituation(double dt) {
|
|||||||
/* mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) ); GBH */
|
/* mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) ); GBH */
|
||||||
BrakeLevelSet( gbh_FS );
|
BrakeLevelSet( gbh_FS );
|
||||||
// don't charge the brakes too often, or we risk overcharging
|
// don't charge the brakes too often, or we risk overcharging
|
||||||
BrakeChargingCooldown = -120.0;
|
BrakeChargingCooldown = -1 * clamp( iVehicleCount * 3, 30, 90 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|||||||
71
DynObj.cpp
71
DynObj.cpp
@@ -849,15 +849,18 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
|||||||
//*************************************************************/// koniec
|
//*************************************************************/// koniec
|
||||||
// wezykow
|
// wezykow
|
||||||
// uginanie zderzakow
|
// uginanie zderzakow
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; ++i) {
|
||||||
{
|
|
||||||
double dist = MoverParameters->Couplers[i].Dist / 2.0;
|
auto const dist { clamp( MoverParameters->Couplers[ i ].Dist / 2.0, -MoverParameters->Couplers[ i ].DmaxB, 0.0 ) };
|
||||||
if (smBuforLewy[i])
|
|
||||||
if (dist < 0)
|
if( dist >= 0.0 ) { continue; }
|
||||||
smBuforLewy[i]->SetTranslate( Math3D::vector3(dist, 0, 0));
|
|
||||||
if (smBuforPrawy[i])
|
if( smBuforLewy[ i ] ) {
|
||||||
if (dist < 0)
|
smBuforLewy[ i ]->SetTranslate( Math3D::vector3( dist, 0, 0 ) );
|
||||||
smBuforPrawy[i]->SetTranslate( Math3D::vector3(dist, 0, 0));
|
}
|
||||||
|
if( smBuforPrawy[ i ] ) {
|
||||||
|
smBuforPrawy[ i ]->SetTranslate( Math3D::vector3( dist, 0, 0 ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // vehicle within 50m
|
} // vehicle within 50m
|
||||||
|
|
||||||
@@ -2204,12 +2207,9 @@ void TDynamicObject::Move(double fDistance)
|
|||||||
// Ra 2F1J: to nie jest stabilne (powoduje rzucanie taborem) i wymaga
|
// Ra 2F1J: to nie jest stabilne (powoduje rzucanie taborem) i wymaga
|
||||||
// dopracowania
|
// dopracowania
|
||||||
fAdjustment = vFront.Length() - fAxleDist; // na łuku będzie ujemny
|
fAdjustment = vFront.Length() - fAxleDist; // na łuku będzie ujemny
|
||||||
// if (fabs(fAdjustment)>0.02) //jeśli jest zbyt dużo, to rozłożyć na kilka
|
// if (fabs(fAdjustment)>0.02) //jeśli jest zbyt dużo, to rozłożyć na kilka przeliczeń (wygasza drgania?)
|
||||||
// przeliczeń
|
|
||||||
// (wygasza drgania?)
|
|
||||||
//{//parę centymetrów trzeba by już skorygować; te błędy mogą się też
|
//{//parę centymetrów trzeba by już skorygować; te błędy mogą się też
|
||||||
// generować na ostrych
|
// generować na ostrych łukach
|
||||||
//łukach
|
|
||||||
// fAdjustment*=0.5; //w jednym kroku korygowany jest ułamek błędu
|
// fAdjustment*=0.5; //w jednym kroku korygowany jest ułamek błędu
|
||||||
//}
|
//}
|
||||||
// else
|
// else
|
||||||
@@ -2784,8 +2784,8 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
auto Frj { 0.0 };
|
auto Frj { 0.0 };
|
||||||
auto osie { 0 };
|
auto osie { 0 };
|
||||||
// 0a. ustal aktualna nastawe zadania sily napedowej i hamowania
|
// 0a. ustal aktualna nastawe zadania sily napedowej i hamowania
|
||||||
if (MoverParameters->Power < 1)
|
if( ( MoverParameters->Power < 1 )
|
||||||
{
|
&& ( ctOwner != nullptr ) ) {
|
||||||
MoverParameters->MainCtrlPos = ctOwner->Controlling()->MainCtrlPos*MoverParameters->MainCtrlPosNo / std::max(1, ctOwner->Controlling()->MainCtrlPosNo);
|
MoverParameters->MainCtrlPos = ctOwner->Controlling()->MainCtrlPos*MoverParameters->MainCtrlPosNo / std::max(1, ctOwner->Controlling()->MainCtrlPosNo);
|
||||||
MoverParameters->ScndCtrlActualPos = ctOwner->Controlling()->ScndCtrlActualPos;
|
MoverParameters->ScndCtrlActualPos = ctOwner->Controlling()->ScndCtrlActualPos;
|
||||||
}
|
}
|
||||||
@@ -3126,7 +3126,10 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
-vPosition.x,
|
-vPosition.x,
|
||||||
vPosition.z,
|
vPosition.z,
|
||||||
vPosition.y };
|
vPosition.y };
|
||||||
TRotation r { 0.0, 0.0, 0.0 };
|
TRotation const r {
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
modelRot.z };
|
||||||
// McZapkie-260202 - dMoveLen przyda sie przy stukocie kol
|
// McZapkie-260202 - dMoveLen przyda sie przy stukocie kol
|
||||||
dDOMoveLen = GetdMoveLen() + MoverParameters->ComputeMovement(dt, dt1, ts, tp, tmpTraction, l, r);
|
dDOMoveLen = GetdMoveLen() + MoverParameters->ComputeMovement(dt, dt1, ts, tp, tmpTraction, l, r);
|
||||||
if( Mechanik )
|
if( Mechanik )
|
||||||
@@ -3620,7 +3623,10 @@ bool TDynamicObject::FastUpdate(double dt)
|
|||||||
-vPosition.x,
|
-vPosition.x,
|
||||||
vPosition.z,
|
vPosition.z,
|
||||||
vPosition.y };
|
vPosition.y };
|
||||||
TRotation r { 0.0, 0.0, 0.0 };
|
TRotation const r {
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
modelRot.z };
|
||||||
// McZapkie: parametry powinny byc pobierane z toru
|
// McZapkie: parametry powinny byc pobierane z toru
|
||||||
// ts.R=MyTrack->fRadius;
|
// ts.R=MyTrack->fRadius;
|
||||||
// ts.Len= Max0R(MoverParameters->BDist,MoverParameters->ADist);
|
// ts.Len= Max0R(MoverParameters->BDist,MoverParameters->ADist);
|
||||||
@@ -3904,7 +3910,7 @@ void TDynamicObject::RenderSounds() {
|
|||||||
}
|
}
|
||||||
// NBMX sygnal odjazdu
|
// NBMX sygnal odjazdu
|
||||||
if( MoverParameters->Doors.has_warning ) {
|
if( MoverParameters->Doors.has_warning ) {
|
||||||
for( auto &door : m_doorsounds ) {
|
for( auto &departuresignalsound : m_departuresignalsounds ) {
|
||||||
// TBD, TODO: per-location door state triggers?
|
// TBD, TODO: per-location door state triggers?
|
||||||
if( ( MoverParameters->DepartureSignal )
|
if( ( MoverParameters->DepartureSignal )
|
||||||
/*
|
/*
|
||||||
@@ -3915,10 +3921,10 @@ void TDynamicObject::RenderSounds() {
|
|||||||
) {
|
) {
|
||||||
// for the autonomous doors play the warning automatically whenever a door is closing
|
// for the autonomous doors play the warning automatically whenever a door is closing
|
||||||
// MC: pod warunkiem ze jest zdefiniowane w chk
|
// MC: pod warunkiem ze jest zdefiniowane w chk
|
||||||
door.sDepartureSignal.play( sound_flags::exclusive | sound_flags::looping );
|
departuresignalsound.play( sound_flags::exclusive | sound_flags::looping );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
door.sDepartureSignal.stop();
|
departuresignalsound.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4227,12 +4233,7 @@ void TDynamicObject::RenderSounds() {
|
|||||||
if( MoverParameters->EventFlag ) {
|
if( MoverParameters->EventFlag ) {
|
||||||
// McZapkie: w razie wykolejenia
|
// McZapkie: w razie wykolejenia
|
||||||
if( true == TestFlag( MoverParameters->DamageFlag, dtrain_out ) ) {
|
if( true == TestFlag( MoverParameters->DamageFlag, dtrain_out ) ) {
|
||||||
if( GetVelocity() > 0 ) {
|
rsDerailment.play( sound_flags::exclusive );
|
||||||
rsDerailment.play();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rsDerailment.stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MoverParameters->EventFlag = false;
|
MoverParameters->EventFlag = false;
|
||||||
@@ -5233,11 +5234,11 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
|||||||
sound_source soundtemplate { sound_placement::general, 25.f };
|
sound_source soundtemplate { sound_placement::general, 25.f };
|
||||||
soundtemplate.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
soundtemplate.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
||||||
soundtemplate.owner( this );
|
soundtemplate.owner( this );
|
||||||
for( auto &door : m_doorsounds ) {
|
for( auto &departuresignalsound : m_departuresignalsounds ) {
|
||||||
// apply configuration to all defined doors, but preserve their individual offsets
|
// apply configuration to all defined doors, but preserve their individual offsets
|
||||||
auto const dooroffset { door.lock.offset() };
|
auto const soundoffset { departuresignalsound.offset() };
|
||||||
door.sDepartureSignal = soundtemplate;
|
departuresignalsound = soundtemplate;
|
||||||
door.sDepartureSignal.offset( dooroffset );
|
departuresignalsound.offset( soundoffset );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5391,7 +5392,6 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
|||||||
// left...
|
// left...
|
||||||
auto const location { glm::vec3 { MoverParameters->Dim.W * 0.5f, MoverParameters->Dim.H * 0.5f, offset } };
|
auto const location { glm::vec3 { MoverParameters->Dim.W * 0.5f, MoverParameters->Dim.H * 0.5f, offset } };
|
||||||
door.placement = side::left;
|
door.placement = side::left;
|
||||||
door.sDepartureSignal.offset( location );
|
|
||||||
door.rsDoorClose.offset( location );
|
door.rsDoorClose.offset( location );
|
||||||
door.rsDoorOpen.offset( location );
|
door.rsDoorOpen.offset( location );
|
||||||
door.lock.offset( location );
|
door.lock.offset( location );
|
||||||
@@ -5403,9 +5403,8 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
|||||||
if( ( sides == "both" )
|
if( ( sides == "both" )
|
||||||
|| ( sides == "right" ) ) {
|
|| ( sides == "right" ) ) {
|
||||||
// ...and right
|
// ...and right
|
||||||
auto const location { glm::vec3 { MoverParameters->Dim.W * -0.5f, MoverParameters->Dim.H * 0.5f, offset } };
|
auto const location { glm::vec3 { MoverParameters->Dim.W * -0.5f, 2.f, offset } };
|
||||||
door.placement = side::right;
|
door.placement = side::right;
|
||||||
door.sDepartureSignal.offset( location );
|
|
||||||
door.rsDoorClose.offset( location );
|
door.rsDoorClose.offset( location );
|
||||||
door.rsDoorOpen.offset( location );
|
door.rsDoorOpen.offset( location );
|
||||||
door.lock.offset( location );
|
door.lock.offset( location );
|
||||||
@@ -5414,6 +5413,10 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
|||||||
door.step_open.offset( location );
|
door.step_open.offset( location );
|
||||||
m_doorsounds.emplace_back( door );
|
m_doorsounds.emplace_back( door );
|
||||||
}
|
}
|
||||||
|
// potential departure sound, one per door (pair) on vehicle centreline
|
||||||
|
sound_source departuresignalsound { sound_placement::general, 25.f };
|
||||||
|
departuresignalsound.offset( glm::vec3{ 0.f, 3.f, offset } );
|
||||||
|
m_departuresignalsounds.emplace_back( departuresignalsound );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
DynObj.h
2
DynObj.h
@@ -319,7 +319,6 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct door_sounds {
|
struct door_sounds {
|
||||||
sound_source sDepartureSignal { sound_placement::general };
|
|
||||||
sound_source rsDoorOpen { sound_placement::general }; // Ra: przeniesione z kabiny
|
sound_source rsDoorOpen { sound_placement::general }; // Ra: przeniesione z kabiny
|
||||||
sound_source rsDoorClose { sound_placement::general };
|
sound_source rsDoorClose { sound_placement::general };
|
||||||
sound_source lock { sound_placement::general };
|
sound_source lock { sound_placement::general };
|
||||||
@@ -446,6 +445,7 @@ private:
|
|||||||
std::array<coupler_sounds, 2> m_couplersounds; // always front and rear
|
std::array<coupler_sounds, 2> m_couplersounds; // always front and rear
|
||||||
std::vector<pantograph_sounds> m_pantographsounds; // typically 2 but can be less (or more?)
|
std::vector<pantograph_sounds> m_pantographsounds; // typically 2 but can be less (or more?)
|
||||||
std::vector<door_sounds> m_doorsounds; // can expect symmetrical arrangement, but don't count on it
|
std::vector<door_sounds> m_doorsounds; // can expect symmetrical arrangement, but don't count on it
|
||||||
|
std::vector<sound_source> m_departuresignalsounds; // single source per door (pair) on the centreline
|
||||||
bool m_doorlocks { false }; // sound helper, current state of door locks
|
bool m_doorlocks { false }; // sound helper, current state of door locks
|
||||||
sound_source sHorn1 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
sound_source sHorn1 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||||
sound_source sHorn2 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
sound_source sHorn2 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||||
|
|||||||
@@ -649,7 +649,7 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
>> uart_conf.updatetime;
|
>> uart_conf.updatetime;
|
||||||
}
|
}
|
||||||
else if( token == "uarttune" ) {
|
else if( token == "uarttune" ) {
|
||||||
Parser.getTokens( 14 );
|
Parser.getTokens( 16 );
|
||||||
Parser
|
Parser
|
||||||
>> uart_conf.mainbrakemin
|
>> uart_conf.mainbrakemin
|
||||||
>> uart_conf.mainbrakemax
|
>> uart_conf.mainbrakemax
|
||||||
@@ -664,7 +664,9 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
>> uart_conf.hvmax
|
>> uart_conf.hvmax
|
||||||
>> uart_conf.hvuart
|
>> uart_conf.hvuart
|
||||||
>> uart_conf.currentmax
|
>> uart_conf.currentmax
|
||||||
>> uart_conf.currentuart;
|
>> uart_conf.currentuart
|
||||||
|
>> uart_conf.lvmax
|
||||||
|
>> uart_conf.lvuart;
|
||||||
}
|
}
|
||||||
else if( token == "uartfeature" ) {
|
else if( token == "uartfeature" ) {
|
||||||
Parser.getTokens( 4 );
|
Parser.getTokens( 4 );
|
||||||
|
|||||||
@@ -657,6 +657,7 @@ struct TCoupling {
|
|||||||
double CForce = 0.0; /*sila z jaka dzialal*/
|
double CForce = 0.0; /*sila z jaka dzialal*/
|
||||||
double Dist = 0.0; /*strzalka ugiecia zderzaków*/
|
double Dist = 0.0; /*strzalka ugiecia zderzaków*/
|
||||||
bool CheckCollision = false; /*czy sprawdzac sile czy pedy*/
|
bool CheckCollision = false; /*czy sprawdzac sile czy pedy*/
|
||||||
|
float stretch_duration { 0.f }; // seconds, elapsed time with excessive force applied to the coupler
|
||||||
|
|
||||||
power_coupling power_high;
|
power_coupling power_high;
|
||||||
// power_coupling power_low; // TODO: implement this
|
// power_coupling power_low; // TODO: implement this
|
||||||
@@ -1142,6 +1143,7 @@ public:
|
|||||||
/*--opis konkretnego egzemplarza taboru*/
|
/*--opis konkretnego egzemplarza taboru*/
|
||||||
TLocation Loc { 0.0, 0.0, 0.0 }; //pozycja pojazdów do wyznaczenia odległości pomiędzy sprzęgami
|
TLocation Loc { 0.0, 0.0, 0.0 }; //pozycja pojazdów do wyznaczenia odległości pomiędzy sprzęgami
|
||||||
TRotation Rot { 0.0, 0.0, 0.0 };
|
TRotation Rot { 0.0, 0.0, 0.0 };
|
||||||
|
glm::vec3 Front{};
|
||||||
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
|
std::array<neighbour_data, 2> Neighbours; // potential collision sources
|
||||||
@@ -1407,6 +1409,8 @@ public:
|
|||||||
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 damage_coupler( int const End );
|
||||||
|
void derail( int const Reason );
|
||||||
bool DirectionForward();
|
bool DirectionForward();
|
||||||
bool DirectionBackward( void );/*! kierunek ruchu*/
|
bool DirectionBackward( void );/*! kierunek ruchu*/
|
||||||
void BrakeLevelSet(double b);
|
void BrakeLevelSet(double b);
|
||||||
@@ -1416,8 +1420,8 @@ public:
|
|||||||
bool ChangeCab(int direction);
|
bool ChangeCab(int direction);
|
||||||
bool CurrentSwitch(bool const State);
|
bool CurrentSwitch(bool const State);
|
||||||
void UpdateBatteryVoltage(double dt);
|
void UpdateBatteryVoltage(double dt);
|
||||||
double ComputeMovement(double dt, double dt1, const TTrackShape &Shape, TTrackParam &Track, TTractionParam &ElectricTraction, const TLocation &NewLoc, TRotation &NewRot); //oblicza przesuniecie pojazdu
|
double ComputeMovement(double dt, double dt1, const TTrackShape &Shape, TTrackParam &Track, TTractionParam &ElectricTraction, TLocation const &NewLoc, TRotation const &NewRot); //oblicza przesuniecie pojazdu
|
||||||
double FastComputeMovement(double dt, const TTrackShape &Shape, TTrackParam &Track, const TLocation &NewLoc, TRotation &NewRot); //oblicza przesuniecie pojazdu - wersja zoptymalizowana
|
double FastComputeMovement(double dt, const TTrackShape &Shape, TTrackParam &Track, TLocation const &NewLoc, TRotation const &NewRot); //oblicza przesuniecie pojazdu - wersja zoptymalizowana
|
||||||
void compute_movement_( double const Deltatime );
|
void compute_movement_( double const Deltatime );
|
||||||
double ShowEngineRotation(int VehN);
|
double ShowEngineRotation(int VehN);
|
||||||
|
|
||||||
@@ -1506,7 +1510,7 @@ public:
|
|||||||
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 const End, double dt);
|
double CouplerForce(int const End, double dt);
|
||||||
void CollisionDetect(int CouplerN, double dt);
|
void CollisionDetect(int const End, double const dt);
|
||||||
/*obrot kol uwzgledniajacy poslizg*/
|
/*obrot kol uwzgledniajacy poslizg*/
|
||||||
double ComputeRotatingWheel(double WForce, double dt, double n) const;
|
double ComputeRotatingWheel(double WForce, double dt, double n) const;
|
||||||
|
|
||||||
|
|||||||
@@ -995,68 +995,140 @@ double TMoverParameters::PipeRatio(void)
|
|||||||
// Q: 20160716
|
// Q: 20160716
|
||||||
// Wykrywanie kolizji
|
// Wykrywanie kolizji
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
void TMoverParameters::CollisionDetect(int CouplerN, double dt)
|
void TMoverParameters::CollisionDetect(int const End, double const dt)
|
||||||
{
|
{
|
||||||
double CCF, Vprev, VprevC;
|
if( Neighbours[ End ].vehicle == nullptr ) { return; } // shouldn't normally happen but, eh
|
||||||
bool VirtualCoupling;
|
|
||||||
|
|
||||||
CCF = 0;
|
auto &coupler { Couplers[ End ] };
|
||||||
// with Couplers[CouplerN] do
|
auto *othervehicle { Neighbours[ End ].vehicle->MoverParameters };
|
||||||
auto &coupler = Couplers[ CouplerN ];
|
auto const otherend { Neighbours[ End ].vehicle_end };
|
||||||
|
auto &othercoupler { othervehicle->Couplers[ otherend ] };
|
||||||
|
|
||||||
if (coupler.Connected != nullptr)
|
auto velocity { V };
|
||||||
{
|
auto othervehiclevelocity { othervehicle->V };
|
||||||
VirtualCoupling = (coupler.CouplingFlag == ctrain_virtual);
|
// calculate collision force and new velocities for involved vehicles
|
||||||
Vprev = V;
|
auto const VirtualCoupling { ( coupler.CouplingFlag == coupling::faux ) };
|
||||||
VprevC = coupler.Connected->V;
|
auto CCF { 0.0 };
|
||||||
switch (CouplerN)
|
|
||||||
{
|
switch( End ) {
|
||||||
case 0:
|
case 0: {
|
||||||
CCF =
|
CCF =
|
||||||
ComputeCollision(
|
ComputeCollision(
|
||||||
V,
|
velocity, othervehiclevelocity,
|
||||||
coupler.Connected->V,
|
TotalMass, othervehicle->TotalMass,
|
||||||
TotalMass,
|
( coupler.beta + othercoupler.beta ) / 2.0,
|
||||||
coupler.Connected->TotalMass,
|
VirtualCoupling )
|
||||||
(coupler.beta + coupler.Connected->Couplers[coupler.ConnectedNr].beta) / 2.0,
|
/ ( dt );
|
||||||
VirtualCoupling)
|
|
||||||
/ (dt);
|
|
||||||
break; // yB: ej ej ej, a po
|
break; // yB: ej ej ej, a po
|
||||||
case 1:
|
}
|
||||||
|
case 1: {
|
||||||
CCF =
|
CCF =
|
||||||
ComputeCollision(
|
ComputeCollision(
|
||||||
coupler.Connected->V,
|
othervehiclevelocity, velocity,
|
||||||
V,
|
othervehicle->TotalMass, TotalMass,
|
||||||
coupler.Connected->TotalMass,
|
( coupler.beta + othercoupler.beta ) / 2.0,
|
||||||
TotalMass,
|
VirtualCoupling )
|
||||||
(coupler.beta + coupler.Connected->Couplers[coupler.ConnectedNr].beta) / 2.0,
|
/ ( dt );
|
||||||
VirtualCoupling)
|
break;
|
||||||
/ (dt);
|
|
||||||
break; // czemu tu jest +0.01??
|
|
||||||
}
|
}
|
||||||
AccS = AccS + (V - Vprev) / dt; // korekta przyspieszenia o siły wynikające ze zderzeń?
|
default: {
|
||||||
coupler.Connected->AccS += (coupler.Connected->V - VprevC) / dt;
|
break;
|
||||||
if ((coupler.Dist > 0) && (!VirtualCoupling))
|
}
|
||||||
if (FuzzyLogic(abs(CCF), 5.0 * (coupler.FmaxC + 1.0), p_coupldmg))
|
}
|
||||||
{ //! zerwanie sprzegu
|
|
||||||
if (SetFlag(DamageFlag, dtrain_coupling))
|
if( ( coupler.Dist < 0 )
|
||||||
|
&& ( 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
|
||||||
|
damage_coupler( End );
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const safevelocitylimit { 15.0 };
|
||||||
|
auto const velocitydifference {
|
||||||
|
glm::length(
|
||||||
|
glm::angleAxis( Rot.Rz, glm::dvec3{ 0, 1, 0 } ) * V
|
||||||
|
- glm::angleAxis( othervehicle->Rot.Rz, glm::dvec3{ 0, 1, 0 } ) * othervehicle->V )
|
||||||
|
* 3.6 }; // m/s -> km/h
|
||||||
|
|
||||||
|
if( velocitydifference > safevelocitylimit ) {
|
||||||
|
// HACK: crude estimation for potential derail, will take place with velocity difference > 15 km/h adjusted for vehicle mass ratio
|
||||||
|
WriteLog( "Bad driving: " + Name + " and " + othervehicle->Name + " collided with velocity " + to_string( velocitydifference, 0 ) + " km/h" );
|
||||||
|
|
||||||
|
if( velocitydifference > safevelocitylimit * ( TotalMass / othervehicle->TotalMass ) ) {
|
||||||
|
derail( 5 );
|
||||||
|
}
|
||||||
|
if( velocitydifference > safevelocitylimit * ( othervehicle->TotalMass / TotalMass ) ) {
|
||||||
|
othervehicle->derail( 5 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// adjust velocity and acceleration of affected vehicles
|
||||||
|
if( false == TestFlag( DamageFlag, dtrain_out ) ) {
|
||||||
|
auto const accelerationchange{ ( velocity - V ) / dt };
|
||||||
|
// if( accelerationchange / AccS < 1.0 ) {
|
||||||
|
// HACK: prevent excessive vehicle pinball cases
|
||||||
|
AccS += accelerationchange;
|
||||||
|
// AccS = clamp( AccS, -2.0, 2.0 );
|
||||||
|
V = velocity;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
if( false == TestFlag( othervehicle->DamageFlag, dtrain_out ) ) {
|
||||||
|
auto const othervehicleaccelerationchange{ ( othervehiclevelocity - othervehicle->V ) / dt };
|
||||||
|
// if( othervehicleaccelerationchange / othervehicle->AccS < 1.0 ) {
|
||||||
|
// HACK: prevent excessive vehicle pinball cases
|
||||||
|
othervehicle->AccS += othervehicleaccelerationchange;
|
||||||
|
othervehicle->V = othervehiclevelocity;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TMoverParameters::damage_coupler( int const End ) {
|
||||||
|
|
||||||
|
if( SetFlag( DamageFlag, dtrain_coupling ) )
|
||||||
EventFlag = true;
|
EventFlag = true;
|
||||||
|
|
||||||
if ((coupler.CouplingFlag & ctrain_pneumatic) == ctrain_pneumatic)
|
auto &coupler { Couplers[ End ] };
|
||||||
AlarmChainFlag = true; // hamowanie nagle - zerwanie przewodow hamulcowych
|
|
||||||
|
if( ( coupler.CouplingFlag & ctrain_pneumatic ) == ctrain_pneumatic ) {
|
||||||
|
// hamowanie nagle - zerwanie przewodow hamulcowych
|
||||||
|
AlarmChainFlag = true;
|
||||||
|
}
|
||||||
|
|
||||||
coupler.CouplingFlag = 0;
|
coupler.CouplingFlag = 0;
|
||||||
|
|
||||||
switch (CouplerN) // wyzerowanie flag podlaczenia ale ciagle sa wirtualnie polaczone
|
if( coupler.Connected != nullptr ) {
|
||||||
{
|
switch( End ) {
|
||||||
case 0:
|
// break connection with other vehicle, if there's any
|
||||||
coupler.Connected->Couplers[1].CouplingFlag = 0;
|
case 0: {
|
||||||
break;
|
coupler.Connected->Couplers[ end::rear ].CouplingFlag = 0;
|
||||||
case 1:
|
|
||||||
coupler.Connected->Couplers[0].CouplingFlag = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 1: {
|
||||||
|
coupler.Connected->Couplers[ end::front ].CouplingFlag = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WriteLog( "Bad driving: " + Name + " broke a coupler" );
|
WriteLog( "Bad driving: " + Name + " broke a coupler" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TMoverParameters::derail( int const Reason ) {
|
||||||
|
|
||||||
|
if( SetFlag( DamageFlag, dtrain_out ) ) {
|
||||||
|
|
||||||
|
DerailReason = Reason; // TODO: enum derail causes
|
||||||
|
EventFlag = true;
|
||||||
|
MainSwitch( false, range_t::local );
|
||||||
|
|
||||||
|
AccS *= 0.65;
|
||||||
|
V *= 0.65;
|
||||||
|
|
||||||
|
WriteLog( "Bad driving: " + Name + " derailed" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1065,7 +1137,7 @@ void TMoverParameters::CollisionDetect(int CouplerN, double dt)
|
|||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShape &Shape,
|
double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShape &Shape,
|
||||||
TTrackParam &Track, TTractionParam &ElectricTraction,
|
TTrackParam &Track, TTractionParam &ElectricTraction,
|
||||||
const TLocation &NewLoc, TRotation &NewRot)
|
TLocation const &NewLoc, TRotation const &NewRot)
|
||||||
{
|
{
|
||||||
const double Vepsilon = 1e-5;
|
const double Vepsilon = 1e-5;
|
||||||
const double Aepsilon = 1e-3; // ASBSpeed=0.8;
|
const double Aepsilon = 1e-3; // ASBSpeed=0.8;
|
||||||
@@ -1099,9 +1171,6 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
|||||||
// TODO: investigate, seems supplied NewRot is always 0 although the code here suggests some actual values are expected
|
// TODO: investigate, seems supplied NewRot is always 0 although the code here suggests some actual values are expected
|
||||||
Loc = NewLoc;
|
Loc = NewLoc;
|
||||||
Rot = NewRot;
|
Rot = NewRot;
|
||||||
NewRot.Rx = 0;
|
|
||||||
NewRot.Ry = 0;
|
|
||||||
NewRot.Rz = 0;
|
|
||||||
|
|
||||||
if (dL == 0) // oblicz przesuniecie}
|
if (dL == 0) // oblicz przesuniecie}
|
||||||
{
|
{
|
||||||
@@ -1230,17 +1299,14 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
|||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
|
|
||||||
double TMoverParameters::FastComputeMovement(double dt, const TTrackShape &Shape,
|
double TMoverParameters::FastComputeMovement(double dt, const TTrackShape &Shape,
|
||||||
TTrackParam &Track, const TLocation &NewLoc,
|
TTrackParam &Track, TLocation const &NewLoc,
|
||||||
TRotation &NewRot)
|
TRotation const &NewRot)
|
||||||
{
|
{
|
||||||
int b;
|
int b;
|
||||||
// T_MoverParameters::FastComputeMovement(dt, Shape, Track, NewLoc, NewRot);
|
// T_MoverParameters::FastComputeMovement(dt, Shape, Track, NewLoc, NewRot);
|
||||||
|
|
||||||
Loc = NewLoc;
|
Loc = NewLoc;
|
||||||
Rot = NewRot;
|
Rot = NewRot;
|
||||||
NewRot.Rx = 0.0;
|
|
||||||
NewRot.Ry = 0.0;
|
|
||||||
NewRot.Rz = 0.0;
|
|
||||||
|
|
||||||
if (dL == 0) // oblicz przesuniecie
|
if (dL == 0) // oblicz przesuniecie
|
||||||
{
|
{
|
||||||
@@ -1716,7 +1782,7 @@ void TMoverParameters::OilPumpCheck( double const Timestep ) {
|
|||||||
OilPump.pressure =
|
OilPump.pressure =
|
||||||
std::max<float>(
|
std::max<float>(
|
||||||
OilPump.pressure_target,
|
OilPump.pressure_target,
|
||||||
OilPump.pressure - 0.01 * Timestep );
|
OilPump.pressure - ( enrot > 5.0 ? 0.05 : 0.035 ) * 0.5 * Timestep );
|
||||||
}
|
}
|
||||||
OilPump.pressure = clamp( OilPump.pressure, 0.f, 1.5f );
|
OilPump.pressure = clamp( OilPump.pressure, 0.f, 1.5f );
|
||||||
}
|
}
|
||||||
@@ -4129,6 +4195,11 @@ void TMoverParameters::ComputeTotalForce(double dt) {
|
|||||||
|
|
||||||
// juz zoptymalizowane:
|
// juz zoptymalizowane:
|
||||||
FStand = FrictionForce(RunningShape.R, RunningTrack.DamageFlag); // siła oporów ruchu
|
FStand = FrictionForce(RunningShape.R, RunningTrack.DamageFlag); // siła oporów ruchu
|
||||||
|
if( true == TestFlag( DamageFlag, dtrain_out ) ) {
|
||||||
|
// HACK: crude way to reduce speed after derailment
|
||||||
|
// TBD, TODO: more accurate approach?
|
||||||
|
FStand *= 1e20;
|
||||||
|
}
|
||||||
double old_nrot = abs(nrot);
|
double old_nrot = abs(nrot);
|
||||||
nrot = v2n(); // przeliczenie prędkości liniowej na obrotową
|
nrot = v2n(); // przeliczenie prędkości liniowej na obrotową
|
||||||
|
|
||||||
@@ -4418,15 +4489,13 @@ double TMoverParameters::CouplerForce( int const End, double dt ) {
|
|||||||
auto &othercoupler { othervehicle->Couplers[ otherend ] };
|
auto &othercoupler { othervehicle->Couplers[ otherend ] };
|
||||||
|
|
||||||
auto const othervehiclemove { ( othervehicle->dMoveLen * DirPatch( End, otherend ) ) };
|
auto const othervehiclemove { ( othervehicle->dMoveLen * DirPatch( End, otherend ) ) };
|
||||||
|
auto const initialdistance { Neighbours[ End ].distance }; // odległość od sprzęgu sąsiada
|
||||||
auto const distancedelta { (
|
auto const distancedelta { (
|
||||||
End == end::front ?
|
End == end::front ?
|
||||||
othervehiclemove - dMoveLen :
|
othervehiclemove - dMoveLen :
|
||||||
dMoveLen - othervehiclemove ) };
|
dMoveLen - othervehiclemove ) };
|
||||||
auto const initialdistance { Neighbours[ End ].distance }; // odległość od sprzęgu sąsiada
|
|
||||||
|
|
||||||
auto const newdistance =
|
auto const newdistance { initialdistance + 10.0 * distancedelta };
|
||||||
initialdistance
|
|
||||||
+ 10.0 * distancedelta;
|
|
||||||
|
|
||||||
auto const dV { V - ( othervehicle->V * DirPatch( End, otherend ) ) };
|
auto const dV { V - ( othervehicle->V * DirPatch( End, otherend ) ) };
|
||||||
auto const absdV { std::abs( dV ) };
|
auto const absdV { std::abs( dV ) };
|
||||||
@@ -4456,11 +4525,15 @@ double TMoverParameters::CouplerForce( int const End, double dt ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
coupler.CheckCollision = false;
|
coupler.CheckCollision = false;
|
||||||
|
coupler.Dist = 0.0;
|
||||||
|
|
||||||
double CF { 0.0 };
|
double CF { 0.0 };
|
||||||
|
|
||||||
if( ( coupler.CouplingFlag != coupling::faux )
|
if( ( coupler.CouplingFlag != coupling::faux )
|
||||||
|| ( initialdistance < 0 ) ) {
|
|| ( initialdistance < 0 ) ) {
|
||||||
|
|
||||||
|
coupler.Dist = clamp( newdistance, -coupler.DmaxB, coupler.DmaxC );
|
||||||
|
|
||||||
double BetaAvg = 0;
|
double BetaAvg = 0;
|
||||||
double Fmax = 0;
|
double Fmax = 0;
|
||||||
|
|
||||||
@@ -4475,8 +4548,8 @@ double TMoverParameters::CouplerForce( int const End, double dt ) {
|
|||||||
Fmax = 0.5 * ( coupler.FmaxC + coupler.FmaxB + othercoupler.FmaxC + othercoupler.FmaxB ) * CouplerTune;
|
Fmax = 0.5 * ( coupler.FmaxC + coupler.FmaxB + othercoupler.FmaxC + othercoupler.FmaxB ) * CouplerTune;
|
||||||
}
|
}
|
||||||
auto const distDelta { std::abs( newdistance ) - std::abs( coupler.Dist ) }; // McZapkie-191103: poprawka na histereze
|
auto const distDelta { std::abs( newdistance ) - std::abs( coupler.Dist ) }; // McZapkie-191103: poprawka na histereze
|
||||||
coupler.Dist = newdistance;
|
|
||||||
if (coupler.Dist > 0) {
|
if (newdistance > 0) {
|
||||||
|
|
||||||
if( distDelta > 0 ) {
|
if( distDelta > 0 ) {
|
||||||
CF = ( -( coupler.SpringKC + othercoupler.SpringKC ) * coupler.Dist / 2.0 ) * DirF( End )
|
CF = ( -( coupler.SpringKC + othercoupler.SpringKC ) * coupler.Dist / 2.0 ) * DirF( End )
|
||||||
@@ -4487,12 +4560,25 @@ double TMoverParameters::CouplerForce( int const End, double dt ) {
|
|||||||
- Fmax * dV * BetaAvg;
|
- Fmax * dV * BetaAvg;
|
||||||
}
|
}
|
||||||
// liczenie sily ze sprezystosci sprzegu
|
// liczenie sily ze sprezystosci sprzegu
|
||||||
if( coupler.Dist > ( coupler.DmaxC + othercoupler.DmaxC ) ) {
|
if( newdistance > ( coupler.DmaxC + othercoupler.DmaxC ) ) {
|
||||||
// zderzenie
|
// zderzenie
|
||||||
coupler.CheckCollision = true;
|
coupler.CheckCollision = true;
|
||||||
}
|
}
|
||||||
|
if( std::abs( CF ) > coupler.FmaxC ) {
|
||||||
|
// coupler is stretched with excessive force, may break
|
||||||
|
coupler.stretch_duration += dt;
|
||||||
|
// give coupler 1 sec of leeway to account for simulation glitches, before checking whether it breaks
|
||||||
|
// (arbitrary) chance to break grows from 10-100% over 10 sec period
|
||||||
|
if( ( coupler.stretch_duration > 1.f )
|
||||||
|
&& ( Random() < ( coupler.stretch_duration * 0.1f * dt ) ) ) {
|
||||||
|
damage_coupler( End );
|
||||||
}
|
}
|
||||||
if( coupler.Dist < 0 ) {
|
}
|
||||||
|
else {
|
||||||
|
coupler.stretch_duration = 0.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( newdistance < 0 ) {
|
||||||
|
|
||||||
if( distDelta > 0 ) {
|
if( distDelta > 0 ) {
|
||||||
CF = ( -( coupler.SpringKB + othercoupler.SpringKB ) * coupler.Dist / 2.0 ) * DirF( End )
|
CF = ( -( coupler.SpringKB + othercoupler.SpringKB ) * coupler.Dist / 2.0 ) * DirF( End )
|
||||||
@@ -4503,7 +4589,7 @@ double TMoverParameters::CouplerForce( int const End, double dt ) {
|
|||||||
- Fmax * dV * BetaAvg;
|
- Fmax * dV * BetaAvg;
|
||||||
}
|
}
|
||||||
// liczenie sily ze sprezystosci zderzaka
|
// liczenie sily ze sprezystosci zderzaka
|
||||||
if( -coupler.Dist > ( coupler.DmaxB + othercoupler.DmaxB ) ) {
|
if( -newdistance > ( coupler.DmaxB + othercoupler.DmaxB ) ) {
|
||||||
// zderzenie
|
// zderzenie
|
||||||
coupler.CheckCollision = true;
|
coupler.CheckCollision = true;
|
||||||
if( ( coupler.CouplerType == TCouplerType::Automatic )
|
if( ( coupler.CouplerType == TCouplerType::Automatic )
|
||||||
@@ -5402,25 +5488,19 @@ double TMoverParameters::TractionForce( double dt ) {
|
|||||||
|
|
||||||
eimv[eimv_ks] = eimv[eimv_Fr] / eimv[eimv_FMAXMAX];
|
eimv[eimv_ks] = eimv[eimv_Fr] / eimv[eimv_FMAXMAX];
|
||||||
eimv[eimv_df] = eimv[eimv_ks] * eimc[eimc_s_dfmax];
|
eimv[eimv_df] = eimv[eimv_ks] * eimc[eimc_s_dfmax];
|
||||||
eimv[eimv_fp] = DirAbsolute * enrot * eimc[eimc_s_p] +
|
eimv[eimv_fp] = DirAbsolute * enrot * eimc[eimc_s_p] + eimv[eimv_df]; // do przemyslenia dzialanie pp z tmpV
|
||||||
eimv[eimv_df]; // do przemyslenia dzialanie pp z tmpV
|
|
||||||
// eimv[eimv_U]:=Max0R(eimv[eimv_Uzsmax],Min0R(eimc[eimc_f_cfu]*eimv[eimv_fp],eimv[eimv_Uzsmax]));
|
// eimv[eimv_U]:=Max0R(eimv[eimv_Uzsmax],Min0R(eimc[eimc_f_cfu]*eimv[eimv_fp],eimv[eimv_Uzsmax]));
|
||||||
// eimv[eimv_pole]:=eimv[eimv_U]/(eimv[eimv_fp]*eimc[eimc_s_cfu]);
|
// eimv[eimv_pole]:=eimv[eimv_U]/(eimv[eimv_fp]*eimc[eimc_s_cfu]);
|
||||||
if ((abs(eimv[eimv_fp]) <= eimv[eimv_fkr]))
|
if ((abs(eimv[eimv_fp]) <= eimv[eimv_fkr]))
|
||||||
eimv[eimv_pole] = eimc[eimc_f_cfu] / eimc[eimc_s_cfu];
|
eimv[eimv_pole] = eimc[eimc_f_cfu] / eimc[eimc_s_cfu];
|
||||||
else
|
else
|
||||||
eimv[eimv_pole] =
|
eimv[eimv_pole] = eimv[eimv_Uzsmax] / eimc[eimc_s_cfu] / abs(eimv[eimv_fp]);
|
||||||
eimv[eimv_Uzsmax] / eimc[eimc_s_cfu] / abs(eimv[eimv_fp]);
|
|
||||||
eimv[eimv_U] = eimv[eimv_pole] * eimv[eimv_fp] * eimc[eimc_s_cfu];
|
eimv[eimv_U] = eimv[eimv_pole] * eimv[eimv_fp] * eimc[eimc_s_cfu];
|
||||||
eimv[eimv_Ic] = (eimv[eimv_fp] - DirAbsolute * enrot * eimc[eimc_s_p]) *
|
eimv[eimv_Ic] = (eimv[eimv_fp] - DirAbsolute * enrot * eimc[eimc_s_p]) * eimc[eimc_s_dfic] * eimv[eimv_pole];
|
||||||
eimc[eimc_s_dfic] * eimv[eimv_pole];
|
|
||||||
eimv[eimv_If] = eimv[eimv_Ic] * eimc[eimc_s_icif];
|
eimv[eimv_If] = eimv[eimv_Ic] * eimc[eimc_s_icif];
|
||||||
eimv[eimv_M] = eimv[eimv_pole] * eimv[eimv_Ic] * eimc[eimc_s_cim];
|
eimv[eimv_M] = eimv[eimv_pole] * eimv[eimv_Ic] * eimc[eimc_s_cim];
|
||||||
eimv[eimv_Ipoj] = (eimv[eimv_Ic] * NPoweredAxles * eimv[eimv_U]) /
|
eimv[eimv_Ipoj] = (eimv[eimv_Ic] * NPoweredAxles * eimv[eimv_U]) / (Voltage - eimc[eimc_f_DU]) + eimc[eimc_f_I0];
|
||||||
(Voltage - eimc[eimc_f_DU]) +
|
eimv[eimv_Pm] = ActiveDir * eimv[eimv_M] * NPoweredAxles * enrot * Pirazy2 / 1000;
|
||||||
eimc[eimc_f_I0];
|
|
||||||
eimv[eimv_Pm] =
|
|
||||||
ActiveDir * eimv[eimv_M] * NPoweredAxles * enrot * Pirazy2 / 1000;
|
|
||||||
eimv[eimv_Pe] = eimv[eimv_Ipoj] * Voltage / 1000;
|
eimv[eimv_Pe] = eimv[eimv_Ipoj] * Voltage / 1000;
|
||||||
eimv[eimv_eta] = eimv[eimv_Pm] / eimv[eimv_Pe];
|
eimv[eimv_eta] = eimv[eimv_Pm] / eimv[eimv_Pe];
|
||||||
|
|
||||||
@@ -5441,7 +5521,7 @@ double TMoverParameters::TractionForce( double dt ) {
|
|||||||
|
|
||||||
if( ( RlistSize > 0 )
|
if( ( RlistSize > 0 )
|
||||||
&& ( ( std::abs( eimv[ eimv_If ] ) > 1.0 )
|
&& ( ( std::abs( eimv[ eimv_If ] ) > 1.0 )
|
||||||
|| ( tmpV > 0.1 ) ) ) {
|
&& ( tmpV > 0.1 ) ) ) {
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while( ( i < RlistSize - 1 )
|
while( ( i < RlistSize - 1 )
|
||||||
|
|||||||
12
Train.cpp
12
Train.cpp
@@ -500,7 +500,7 @@ dictionary_source *TTrain::GetTrainState() {
|
|||||||
// induction motor state data
|
// induction motor state data
|
||||||
char const *TXTT[ 10 ] = { "fd", "fdt", "fdb", "pd", "pdt", "pdb", "itothv", "1", "2", "3" };
|
char const *TXTT[ 10 ] = { "fd", "fdt", "fdb", "pd", "pdt", "pdb", "itothv", "1", "2", "3" };
|
||||||
char const *TXTC[ 10 ] = { "fr", "frt", "frb", "pr", "prt", "prb", "im", "vm", "ihv", "uhv" };
|
char const *TXTC[ 10 ] = { "fr", "frt", "frb", "pr", "prt", "prb", "im", "vm", "ihv", "uhv" };
|
||||||
char const *TXTD[ 10 ] = { "enrot", "nrot", "fill_des", "fill_real", "clutch_des", "clutch_real", "water_temp", "oil_press", "res1", "res2" };
|
char const *TXTD[ 10 ] = { "enrot", "nrot", "fill_des", "fill_real", "clutch_des", "clutch_real", "water_temp", "oil_press", "engine_temp", "res1" };
|
||||||
char const *TXTP[ 3 ] = { "bc", "bp", "sp" };
|
char const *TXTP[ 3 ] = { "bc", "bp", "sp" };
|
||||||
for( int j = 0; j < 10; ++j )
|
for( int j = 0; j < 10; ++j )
|
||||||
dict->insert( ( "eimp_t_" + std::string( TXTT[ j ] ) ), fEIMParams[ 0 ][ j ] );
|
dict->insert( ( "eimp_t_" + std::string( TXTT[ j ] ) ), fEIMParams[ 0 ][ j ] );
|
||||||
@@ -588,6 +588,7 @@ TTrain::get_state() const {
|
|||||||
btLampkaNadmWent.GetValue(),
|
btLampkaNadmWent.GetValue(),
|
||||||
btLampkaWysRozr.GetValue(),
|
btLampkaWysRozr.GetValue(),
|
||||||
btLampkaOgrzewanieSkladu.GetValue(),
|
btLampkaOgrzewanieSkladu.GetValue(),
|
||||||
|
static_cast<std::uint8_t>( iCabn ),
|
||||||
btHaslerBrakes.GetValue(),
|
btHaslerBrakes.GetValue(),
|
||||||
btHaslerCurrent.GetValue(),
|
btHaslerCurrent.GetValue(),
|
||||||
( TestFlag( mvOccupied->SecuritySystem.Status, s_CAalarm ) || TestFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ) ),
|
( TestFlag( mvOccupied->SecuritySystem.Status, s_CAalarm ) || TestFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ) ),
|
||||||
@@ -597,7 +598,8 @@ TTrain::get_state() const {
|
|||||||
static_cast<float>( mvOccupied->PipePress ),
|
static_cast<float>( mvOccupied->PipePress ),
|
||||||
static_cast<float>( mvOccupied->BrakePress ),
|
static_cast<float>( mvOccupied->BrakePress ),
|
||||||
fHVoltage,
|
fHVoltage,
|
||||||
{ fHCurrent[ ( mvControlled->TrainType & dt_EZT ) ? 0 : 1 ], fHCurrent[ 2 ], fHCurrent[ 3 ] }
|
{ fHCurrent[ ( mvControlled->TrainType & dt_EZT ) ? 0 : 1 ], fHCurrent[ 2 ], fHCurrent[ 3 ] },
|
||||||
|
ggLVoltage.GetValue()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5375,7 +5377,9 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
in++;
|
in++;
|
||||||
iPowerNo = in;
|
iPowerNo = in;
|
||||||
}
|
}
|
||||||
if ((in < 8) && (p->MoverParameters->EngineType==TEngineType::DieselEngine))
|
if ((in < 8)
|
||||||
|
&& ((p->MoverParameters->EngineType==TEngineType::DieselEngine)
|
||||||
|
||(p->MoverParameters->EngineType==TEngineType::DieselElectric)))
|
||||||
{
|
{
|
||||||
fDieselParams[1 + in][0] = p->MoverParameters->enrot*60;
|
fDieselParams[1 + in][0] = p->MoverParameters->enrot*60;
|
||||||
fDieselParams[1 + in][1] = p->MoverParameters->nrot;
|
fDieselParams[1 + in][1] = p->MoverParameters->nrot;
|
||||||
@@ -5385,7 +5389,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
fDieselParams[1 + in][5] = p->MoverParameters->dizel_engage;
|
fDieselParams[1 + in][5] = p->MoverParameters->dizel_engage;
|
||||||
fDieselParams[1 + in][6] = p->MoverParameters->dizel_heat.Twy;
|
fDieselParams[1 + in][6] = p->MoverParameters->dizel_heat.Twy;
|
||||||
fDieselParams[1 + in][7] = p->MoverParameters->OilPump.pressure;
|
fDieselParams[1 + in][7] = p->MoverParameters->OilPump.pressure;
|
||||||
//fDieselParams[1 + in][8] = p->MoverParameters->
|
fDieselParams[1 + in][8] = p->MoverParameters->dizel_heat.Ts;
|
||||||
//fDieselParams[1 + in][9] = p->MoverParameters->
|
//fDieselParams[1 + in][9] = p->MoverParameters->
|
||||||
bMains[in] = p->MoverParameters->Mains;
|
bMains[in] = p->MoverParameters->Mains;
|
||||||
fCntVol[in] = p->MoverParameters->BatteryVoltage;
|
fCntVol[in] = p->MoverParameters->BatteryVoltage;
|
||||||
|
|||||||
10
Train.h
10
Train.h
@@ -69,8 +69,10 @@ public:
|
|||||||
find( TSubModel const *Control ) const;
|
find( TSubModel const *Control ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TTrain
|
class TTrain {
|
||||||
{
|
|
||||||
|
friend class drivingaid_panel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// types
|
// types
|
||||||
struct state_t {
|
struct state_t {
|
||||||
@@ -88,6 +90,7 @@ class TTrain
|
|||||||
std::uint8_t ventilator_overload;
|
std::uint8_t ventilator_overload;
|
||||||
std::uint8_t motor_overload_threshold;
|
std::uint8_t motor_overload_threshold;
|
||||||
std::uint8_t train_heating;
|
std::uint8_t train_heating;
|
||||||
|
std::uint8_t cab;
|
||||||
std::uint8_t recorder_braking;
|
std::uint8_t recorder_braking;
|
||||||
std::uint8_t recorder_power;
|
std::uint8_t recorder_power;
|
||||||
std::uint8_t alerter_sound;
|
std::uint8_t alerter_sound;
|
||||||
@@ -98,6 +101,7 @@ class TTrain
|
|||||||
float brake_pressure;
|
float brake_pressure;
|
||||||
float hv_voltage;
|
float hv_voltage;
|
||||||
std::array<float, 3> hv_current;
|
std::array<float, 3> hv_current;
|
||||||
|
float lv_voltage;
|
||||||
};
|
};
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
@@ -626,7 +630,7 @@ public: // reszta może by?publiczna
|
|||||||
*/
|
*/
|
||||||
// McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc
|
// McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc
|
||||||
std::array<TCab, maxcab + 1> Cabine; // przedzial maszynowy, kabina 1 (A), kabina 2 (B)
|
std::array<TCab, maxcab + 1> Cabine; // przedzial maszynowy, kabina 1 (A), kabina 2 (B)
|
||||||
int iCabn { 0 };
|
int iCabn { 0 }; // 0: mid, 1: front, 2: rear
|
||||||
// McZapkie: do poruszania sie po kabinie
|
// McZapkie: do poruszania sie po kabinie
|
||||||
Math3D::vector3 pMechSittingPosition; // ABu 180404
|
Math3D::vector3 pMechSittingPosition; // ABu 180404
|
||||||
Math3D::vector3 MirrorPosition( bool lewe );
|
Math3D::vector3 MirrorPosition( bool lewe );
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "mtable.h"
|
#include "mtable.h"
|
||||||
#include "Train.h"
|
#include "Train.h"
|
||||||
|
#include "Button.h"
|
||||||
#include "Driver.h"
|
#include "Driver.h"
|
||||||
#include "AnimModel.h"
|
#include "AnimModel.h"
|
||||||
#include "DynObj.h"
|
#include "DynObj.h"
|
||||||
@@ -135,12 +136,14 @@ drivingaid_panel::update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::string textline =
|
std::string textline = (
|
||||||
( true == TestFlag( mover->SecuritySystem.Status, s_aware ) ?
|
( ( true == TestFlag( mover->SecuritySystem.Status, s_aware ) )
|
||||||
|
&& ( train != nullptr )
|
||||||
|
&& ( train->fBlinkTimer > 0 ) ) ?
|
||||||
locale::strings[ locale::string::driver_aid_alerter ] :
|
locale::strings[ locale::string::driver_aid_alerter ] :
|
||||||
" " );
|
" " );
|
||||||
textline +=
|
textline += (
|
||||||
( true == TestFlag( mover->SecuritySystem.Status, s_active ) ?
|
( true == TestFlag( mover->SecuritySystem.Status, s_active ) ) ?
|
||||||
locale::strings[ locale::string::driver_aid_shp ] :
|
locale::strings[ locale::string::driver_aid_shp ] :
|
||||||
" " );
|
" " );
|
||||||
|
|
||||||
@@ -961,6 +964,13 @@ debug_panel::update_section_scenario( std::vector<text_line> &Output ) {
|
|||||||
textline = "Cloud cover: " + to_string( Global.Overcast, 3 );
|
textline = "Cloud cover: " + to_string( Global.Overcast, 3 );
|
||||||
textline += "\nLight level: " + to_string( Global.fLuminance, 3 );
|
textline += "\nLight level: " + to_string( Global.fLuminance, 3 );
|
||||||
if( Global.FakeLight ) { textline += "(*)"; }
|
if( Global.FakeLight ) { textline += "(*)"; }
|
||||||
|
textline +=
|
||||||
|
"\nWind: azimuth "
|
||||||
|
+ to_string( simulation::Environment.wind_azimuth(), 0 ) // ma być azymut, czyli 0 na północy i rośnie na wschód
|
||||||
|
+ " "
|
||||||
|
+ std::string( "N NEE SES SWW NW" )
|
||||||
|
.substr( 0 + 2 * std::floor( std::fmod( 8 + ( glm::radians( simulation::Environment.wind_azimuth() ) + 0.5 * M_PI_4 ) / M_PI_4, 8 ) ), 2 )
|
||||||
|
+ ", " + to_string( glm::length( simulation::Environment.wind() ), 1 ) + " m/s";
|
||||||
textline += "\nAir temperature: " + to_string( Global.AirTemperature, 1 ) + " deg C";
|
textline += "\nAir temperature: " + to_string( Global.AirTemperature, 1 ) + " deg C";
|
||||||
|
|
||||||
Output.emplace_back( textline, Global.UITextColor );
|
Output.emplace_back( textline, Global.UITextColor );
|
||||||
|
|||||||
@@ -61,9 +61,9 @@ smoke_source::particle_emitter::initialize( smoke_particle &Particle ) {
|
|||||||
auto const azimuthalangle { glm::radians( Random( -180, 180 ) ) }; // phi
|
auto const azimuthalangle { glm::radians( Random( -180, 180 ) ) }; // phi
|
||||||
// convert spherical coordinates to opengl coordinates
|
// convert spherical coordinates to opengl coordinates
|
||||||
auto const launchvector { glm::vec3(
|
auto const launchvector { glm::vec3(
|
||||||
std::sin( polarangle ) * std::sin( azimuthalangle ),
|
std::sin( polarangle ) * std::sin( azimuthalangle ) * -1,
|
||||||
std::cos( polarangle ),
|
std::cos( polarangle ),
|
||||||
std::sin( polarangle ) * std::cos( azimuthalangle ) * -1 ) };
|
std::sin( polarangle ) * std::cos( azimuthalangle ) ) };
|
||||||
auto const launchvelocity { static_cast<float>( Random( velocity[ value_limit::min ], velocity[ value_limit::max ] ) ) };
|
auto const launchvelocity { static_cast<float>( Random( velocity[ value_limit::min ], velocity[ value_limit::max ] ) ) };
|
||||||
|
|
||||||
Particle.velocity = launchvector * launchvelocity;
|
Particle.velocity = launchvector * launchvelocity;
|
||||||
|
|||||||
@@ -194,13 +194,17 @@ world_environment::update_wind() {
|
|||||||
|
|
||||||
m_wind.change_time -= timedelta;
|
m_wind.change_time -= timedelta;
|
||||||
if( m_wind.change_time < 0 ) {
|
if( m_wind.change_time < 0 ) {
|
||||||
m_wind.change_time = Random( 5, 30 );
|
m_wind.change_time = Random( 5, 15 );
|
||||||
m_wind.velocity_change = Random( -1, 1 );
|
m_wind.velocity_change = Random( -0.2, 0.2 );
|
||||||
if( Random() < 0.2 ) {
|
if( Random() < 0.05 ) {
|
||||||
// changes in wind direction should be less frequent than changes in wind speed
|
// changes in wind direction should be less frequent than changes in wind speed
|
||||||
// TBD, TODO: configuration-driven direction change frequency
|
// TBD, TODO: configuration-driven direction change frequency
|
||||||
m_wind.azimuth_change = Random( -5, 5 );
|
m_wind.azimuth_change = Random( -5, 5 );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// keep direction change periods short, to avoid too drastic changes in direction
|
||||||
|
m_wind.azimuth_change = 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TBD, TODO: wind configuration
|
// TBD, TODO: wind configuration
|
||||||
m_wind.azimuth = clamp_circular( m_wind.azimuth + m_wind.azimuth_change * timedelta );
|
m_wind.azimuth = clamp_circular( m_wind.azimuth + m_wind.azimuth_change * timedelta );
|
||||||
@@ -213,9 +217,9 @@ world_environment::update_wind() {
|
|||||||
m_wind.vector =
|
m_wind.vector =
|
||||||
std::max( 0.f, m_wind.velocity )
|
std::max( 0.f, m_wind.velocity )
|
||||||
* glm::vec3(
|
* glm::vec3(
|
||||||
std::sin( polarangle ) * std::sin( azimuthalangle ),
|
std::sin( polarangle ) * std::sin( azimuthalangle ) * -1,
|
||||||
std::cos( polarangle ),
|
std::cos( polarangle ),
|
||||||
std::sin( polarangle ) * std::cos( azimuthalangle ) * -1 );
|
std::sin( polarangle ) * std::cos( azimuthalangle ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ public:
|
|||||||
glm::vec3 const &
|
glm::vec3 const &
|
||||||
wind() const {
|
wind() const {
|
||||||
return m_wind.vector; }
|
return m_wind.vector; }
|
||||||
|
float const &
|
||||||
|
wind_azimuth() const {
|
||||||
|
return m_wind.azimuth; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
|
|||||||
@@ -56,14 +56,15 @@ basic_station::update_load( TDynamicObject *First, Mtable::TTrainParameters &Sch
|
|||||||
// NOTE: for the time being we're doing simple, random load change calculation
|
// NOTE: for the time being we're doing simple, random load change calculation
|
||||||
// TODO: exchange driven by station parameters and time of the day
|
// TODO: exchange driven by station parameters and time of the day
|
||||||
auto unloadcount = static_cast<int>(
|
auto unloadcount = static_cast<int>(
|
||||||
|
TestFlag( parameters.DamageFlag, dtrain_out ) ? parameters.LoadAmount :
|
||||||
laststop ? parameters.LoadAmount :
|
laststop ? parameters.LoadAmount :
|
||||||
firststop ? 0 :
|
firststop ? 0 :
|
||||||
std::min<float>(
|
std::min<float>(
|
||||||
parameters.LoadAmount,
|
parameters.LoadAmount,
|
||||||
Random( parameters.MaxLoad * 0.15f * stationsizemodifier ) ) );
|
Random( parameters.MaxLoad * 0.15f * stationsizemodifier ) ) );
|
||||||
auto loadcount = static_cast<int>(
|
auto loadcount = static_cast<int>(
|
||||||
laststop ?
|
TestFlag( parameters.DamageFlag, dtrain_out ) ? 0 :
|
||||||
0 :
|
laststop ? 0 :
|
||||||
Random( parameters.MaxLoad * 0.15f * stationsizemodifier ) );
|
Random( parameters.MaxLoad * 0.15f * stationsizemodifier ) );
|
||||||
if( true == firststop ) {
|
if( true == firststop ) {
|
||||||
// larger group at the initial station
|
// larger group at the initial station
|
||||||
|
|||||||
15
uart.cpp
15
uart.cpp
@@ -242,6 +242,12 @@ void uart_input::poll()
|
|||||||
uint16_t current1 = (uint16_t)std::min(conf.currentuart, trainstate.hv_current[0] / conf.currentmax * conf.currentuart);
|
uint16_t current1 = (uint16_t)std::min(conf.currentuart, trainstate.hv_current[0] / conf.currentmax * conf.currentuart);
|
||||||
uint16_t current2 = (uint16_t)std::min(conf.currentuart, trainstate.hv_current[1] / conf.currentmax * conf.currentuart);
|
uint16_t current2 = (uint16_t)std::min(conf.currentuart, trainstate.hv_current[1] / conf.currentmax * conf.currentuart);
|
||||||
uint16_t current3 = (uint16_t)std::min(conf.currentuart, trainstate.hv_current[2] / conf.currentmax * conf.currentuart);
|
uint16_t current3 = (uint16_t)std::min(conf.currentuart, trainstate.hv_current[2] / conf.currentmax * conf.currentuart);
|
||||||
|
uint16_t lv_voltage = (uint16_t)std::min( conf.lvuart, trainstate.lv_voltage / conf.lvmax * conf.lvuart );
|
||||||
|
|
||||||
|
if( trainstate.cab > 0 ) {
|
||||||
|
// NOTE: moving from a cab to engine room doesn't change cab indicator
|
||||||
|
m_trainstatecab = trainstate.cab - 1;
|
||||||
|
}
|
||||||
|
|
||||||
std::array<uint8_t, 31> buffer {
|
std::array<uint8_t, 31> buffer {
|
||||||
//byte 0
|
//byte 0
|
||||||
@@ -271,7 +277,8 @@ void uart_input::poll()
|
|||||||
| trainstate.compressor_overload << 6),
|
| trainstate.compressor_overload << 6),
|
||||||
//byte 6
|
//byte 6
|
||||||
(uint8_t)(
|
(uint8_t)(
|
||||||
trainstate.recorder_braking << 3
|
m_trainstatecab << 2
|
||||||
|
| trainstate.recorder_braking << 3
|
||||||
| trainstate.recorder_power << 4
|
| trainstate.recorder_power << 4
|
||||||
| trainstate.radio_stop <<5
|
| trainstate.radio_stop <<5
|
||||||
| trainstate.alerter_sound << 7),
|
| trainstate.alerter_sound << 7),
|
||||||
@@ -289,8 +296,10 @@ void uart_input::poll()
|
|||||||
SPLIT_INT16(current2),
|
SPLIT_INT16(current2),
|
||||||
//byte 19-20
|
//byte 19-20
|
||||||
SPLIT_INT16(current3),
|
SPLIT_INT16(current3),
|
||||||
//byte 21-30
|
//byte 21-22
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
SPLIT_INT16(lv_voltage),
|
||||||
|
//byte 23-30
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
if (conf.debug)
|
if (conf.debug)
|
||||||
|
|||||||
3
uart.h
3
uart.h
@@ -27,6 +27,8 @@ public:
|
|||||||
float hvuart = 65535.0f;
|
float hvuart = 65535.0f;
|
||||||
float currentmax = 10000.0f;
|
float currentmax = 10000.0f;
|
||||||
float currentuart = 65535.0f;
|
float currentuart = 65535.0f;
|
||||||
|
float lvmax = 150.0f;
|
||||||
|
float lvuart = 65535.0f;
|
||||||
|
|
||||||
bool mainenable = true;
|
bool mainenable = true;
|
||||||
bool scndenable = true;
|
bool scndenable = true;
|
||||||
@@ -66,4 +68,5 @@ private:
|
|||||||
std::chrono::time_point<std::chrono::high_resolution_clock> last_update;
|
std::chrono::time_point<std::chrono::high_resolution_clock> last_update;
|
||||||
conf_t conf;
|
conf_t conf;
|
||||||
bool data_pending = false;
|
bool data_pending = false;
|
||||||
|
std::uint8_t m_trainstatecab { 0 }; // helper, keeps track of last active cab. 0: front cab, 1: rear cab
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user