mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 17:29: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 ) {
|
||||
// check signals ahead
|
||||
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 ) {
|
||||
// jeśli jest mienięty poprzedni semafor a wcześniej
|
||||
// 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 */
|
||||
BrakeLevelSet( gbh_FS );
|
||||
// don't charge the brakes too often, or we risk overcharging
|
||||
BrakeChargingCooldown = -120.0;
|
||||
BrakeChargingCooldown = -1 * clamp( iVehicleCount * 3, 30, 90 );
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
67
DynObj.cpp
67
DynObj.cpp
@@ -849,16 +849,19 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
//*************************************************************/// koniec
|
||||
// wezykow
|
||||
// uginanie zderzakow
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
double dist = MoverParameters->Couplers[i].Dist / 2.0;
|
||||
if (smBuforLewy[i])
|
||||
if (dist < 0)
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
|
||||
auto const dist { clamp( MoverParameters->Couplers[ i ].Dist / 2.0, -MoverParameters->Couplers[ i ].DmaxB, 0.0 ) };
|
||||
|
||||
if( dist >= 0.0 ) { continue; }
|
||||
|
||||
if( smBuforLewy[ i ] ) {
|
||||
smBuforLewy[ i ]->SetTranslate( Math3D::vector3( dist, 0, 0 ) );
|
||||
if (smBuforPrawy[i])
|
||||
if (dist < 0)
|
||||
}
|
||||
if( smBuforPrawy[ i ] ) {
|
||||
smBuforPrawy[ i ]->SetTranslate( Math3D::vector3( dist, 0, 0 ) );
|
||||
}
|
||||
}
|
||||
} // vehicle within 50m
|
||||
|
||||
// Winger 160204 - podnoszenie pantografow
|
||||
@@ -2204,12 +2207,9 @@ void TDynamicObject::Move(double fDistance)
|
||||
// Ra 2F1J: to nie jest stabilne (powoduje rzucanie taborem) i wymaga
|
||||
// dopracowania
|
||||
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
|
||||
// przeliczeń
|
||||
// (wygasza drgania?)
|
||||
// if (fabs(fAdjustment)>0.02) //jeśli jest zbyt dużo, to rozłożyć na kilka przeliczeń (wygasza drgania?)
|
||||
//{//parę centymetrów trzeba by już skorygować; te błędy mogą się też
|
||||
// generować na ostrych
|
||||
//łukach
|
||||
// generować na ostrych łukach
|
||||
// fAdjustment*=0.5; //w jednym kroku korygowany jest ułamek błędu
|
||||
//}
|
||||
// else
|
||||
@@ -2784,8 +2784,8 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
auto Frj { 0.0 };
|
||||
auto osie { 0 };
|
||||
// 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->ScndCtrlActualPos = ctOwner->Controlling()->ScndCtrlActualPos;
|
||||
}
|
||||
@@ -3126,7 +3126,10 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
-vPosition.x,
|
||||
vPosition.z,
|
||||
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
|
||||
dDOMoveLen = GetdMoveLen() + MoverParameters->ComputeMovement(dt, dt1, ts, tp, tmpTraction, l, r);
|
||||
if( Mechanik )
|
||||
@@ -3620,7 +3623,10 @@ bool TDynamicObject::FastUpdate(double dt)
|
||||
-vPosition.x,
|
||||
vPosition.z,
|
||||
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
|
||||
// ts.R=MyTrack->fRadius;
|
||||
// ts.Len= Max0R(MoverParameters->BDist,MoverParameters->ADist);
|
||||
@@ -3904,7 +3910,7 @@ void TDynamicObject::RenderSounds() {
|
||||
}
|
||||
// NBMX sygnal odjazdu
|
||||
if( MoverParameters->Doors.has_warning ) {
|
||||
for( auto &door : m_doorsounds ) {
|
||||
for( auto &departuresignalsound : m_departuresignalsounds ) {
|
||||
// TBD, TODO: per-location door state triggers?
|
||||
if( ( MoverParameters->DepartureSignal )
|
||||
/*
|
||||
@@ -3915,10 +3921,10 @@ void TDynamicObject::RenderSounds() {
|
||||
) {
|
||||
// for the autonomous doors play the warning automatically whenever a door is closing
|
||||
// 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 {
|
||||
door.sDepartureSignal.stop();
|
||||
departuresignalsound.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4227,12 +4233,7 @@ void TDynamicObject::RenderSounds() {
|
||||
if( MoverParameters->EventFlag ) {
|
||||
// McZapkie: w razie wykolejenia
|
||||
if( true == TestFlag( MoverParameters->DamageFlag, dtrain_out ) ) {
|
||||
if( GetVelocity() > 0 ) {
|
||||
rsDerailment.play();
|
||||
}
|
||||
else {
|
||||
rsDerailment.stop();
|
||||
}
|
||||
rsDerailment.play( sound_flags::exclusive );
|
||||
}
|
||||
|
||||
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 };
|
||||
soundtemplate.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
||||
soundtemplate.owner( this );
|
||||
for( auto &door : m_doorsounds ) {
|
||||
for( auto &departuresignalsound : m_departuresignalsounds ) {
|
||||
// apply configuration to all defined doors, but preserve their individual offsets
|
||||
auto const dooroffset { door.lock.offset() };
|
||||
door.sDepartureSignal = soundtemplate;
|
||||
door.sDepartureSignal.offset( dooroffset );
|
||||
auto const soundoffset { departuresignalsound.offset() };
|
||||
departuresignalsound = soundtemplate;
|
||||
departuresignalsound.offset( soundoffset );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5391,7 +5392,6 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
// left...
|
||||
auto const location { glm::vec3 { MoverParameters->Dim.W * 0.5f, MoverParameters->Dim.H * 0.5f, offset } };
|
||||
door.placement = side::left;
|
||||
door.sDepartureSignal.offset( location );
|
||||
door.rsDoorClose.offset( location );
|
||||
door.rsDoorOpen.offset( location );
|
||||
door.lock.offset( location );
|
||||
@@ -5403,9 +5403,8 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
if( ( sides == "both" )
|
||||
|| ( sides == "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.sDepartureSignal.offset( location );
|
||||
door.rsDoorClose.offset( location );
|
||||
door.rsDoorOpen.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 );
|
||||
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 {
|
||||
sound_source sDepartureSignal { sound_placement::general };
|
||||
sound_source rsDoorOpen { sound_placement::general }; // Ra: przeniesione z kabiny
|
||||
sound_source rsDoorClose { 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::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<sound_source> m_departuresignalsounds; // single source per door (pair) on the centreline
|
||||
bool m_doorlocks { false }; // sound helper, current state of door locks
|
||||
sound_source sHorn1 { 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;
|
||||
}
|
||||
else if( token == "uarttune" ) {
|
||||
Parser.getTokens( 14 );
|
||||
Parser.getTokens( 16 );
|
||||
Parser
|
||||
>> uart_conf.mainbrakemin
|
||||
>> uart_conf.mainbrakemax
|
||||
@@ -664,7 +664,9 @@ global_settings::ConfigParse(cParser &Parser) {
|
||||
>> uart_conf.hvmax
|
||||
>> uart_conf.hvuart
|
||||
>> uart_conf.currentmax
|
||||
>> uart_conf.currentuart;
|
||||
>> uart_conf.currentuart
|
||||
>> uart_conf.lvmax
|
||||
>> uart_conf.lvuart;
|
||||
}
|
||||
else if( token == "uartfeature" ) {
|
||||
Parser.getTokens( 4 );
|
||||
|
||||
@@ -657,6 +657,7 @@ struct TCoupling {
|
||||
double CForce = 0.0; /*sila z jaka dzialal*/
|
||||
double Dist = 0.0; /*strzalka ugiecia zderzaków*/
|
||||
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_low; // TODO: implement this
|
||||
@@ -1142,6 +1143,7 @@ public:
|
||||
/*--opis konkretnego egzemplarza taboru*/
|
||||
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 };
|
||||
glm::vec3 Front{};
|
||||
std::string Name; /*nazwa wlasna*/
|
||||
TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami
|
||||
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);
|
||||
int DettachStatus(int ConnectNo);
|
||||
bool Dettach(int ConnectNo);
|
||||
void damage_coupler( int const End );
|
||||
void derail( int const Reason );
|
||||
bool DirectionForward();
|
||||
bool DirectionBackward( void );/*! kierunek ruchu*/
|
||||
void BrakeLevelSet(double b);
|
||||
@@ -1416,8 +1420,8 @@ public:
|
||||
bool ChangeCab(int direction);
|
||||
bool CurrentSwitch(bool const State);
|
||||
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 FastComputeMovement(double dt, const TTrackShape &Shape, TTrackParam &Track, const TLocation &NewLoc, TRotation &NewRot); //oblicza przesuniecie pojazdu - wersja zoptymalizowana
|
||||
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, TLocation const &NewLoc, TRotation const &NewRot); //oblicza przesuniecie pojazdu - wersja zoptymalizowana
|
||||
void compute_movement_( double const Deltatime );
|
||||
double ShowEngineRotation(int VehN);
|
||||
|
||||
@@ -1506,7 +1510,7 @@ public:
|
||||
double BrakeForceP(double press, double velocity);
|
||||
double BrakeForce(const TTrackParam &Track);
|
||||
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*/
|
||||
double ComputeRotatingWheel(double WForce, double dt, double n) const;
|
||||
|
||||
|
||||
@@ -995,68 +995,140 @@ double TMoverParameters::PipeRatio(void)
|
||||
// Q: 20160716
|
||||
// Wykrywanie kolizji
|
||||
// *************************************************************************************************
|
||||
void TMoverParameters::CollisionDetect(int CouplerN, double dt)
|
||||
void TMoverParameters::CollisionDetect(int const End, double const dt)
|
||||
{
|
||||
double CCF, Vprev, VprevC;
|
||||
bool VirtualCoupling;
|
||||
if( Neighbours[ End ].vehicle == nullptr ) { return; } // shouldn't normally happen but, eh
|
||||
|
||||
CCF = 0;
|
||||
// with Couplers[CouplerN] do
|
||||
auto &coupler = Couplers[ CouplerN ];
|
||||
auto &coupler { Couplers[ End ] };
|
||||
auto *othervehicle { Neighbours[ End ].vehicle->MoverParameters };
|
||||
auto const otherend { Neighbours[ End ].vehicle_end };
|
||||
auto &othercoupler { othervehicle->Couplers[ otherend ] };
|
||||
|
||||
if (coupler.Connected != nullptr)
|
||||
{
|
||||
VirtualCoupling = (coupler.CouplingFlag == ctrain_virtual);
|
||||
Vprev = V;
|
||||
VprevC = coupler.Connected->V;
|
||||
switch (CouplerN)
|
||||
{
|
||||
case 0:
|
||||
auto velocity { V };
|
||||
auto othervehiclevelocity { othervehicle->V };
|
||||
// calculate collision force and new velocities for involved vehicles
|
||||
auto const VirtualCoupling { ( coupler.CouplingFlag == coupling::faux ) };
|
||||
auto CCF { 0.0 };
|
||||
|
||||
switch( End ) {
|
||||
case 0: {
|
||||
CCF =
|
||||
ComputeCollision(
|
||||
V,
|
||||
coupler.Connected->V,
|
||||
TotalMass,
|
||||
coupler.Connected->TotalMass,
|
||||
(coupler.beta + coupler.Connected->Couplers[coupler.ConnectedNr].beta) / 2.0,
|
||||
velocity, othervehiclevelocity,
|
||||
TotalMass, othervehicle->TotalMass,
|
||||
( coupler.beta + othercoupler.beta ) / 2.0,
|
||||
VirtualCoupling )
|
||||
/ ( dt );
|
||||
break; // yB: ej ej ej, a po
|
||||
case 1:
|
||||
}
|
||||
case 1: {
|
||||
CCF =
|
||||
ComputeCollision(
|
||||
coupler.Connected->V,
|
||||
V,
|
||||
coupler.Connected->TotalMass,
|
||||
TotalMass,
|
||||
(coupler.beta + coupler.Connected->Couplers[coupler.ConnectedNr].beta) / 2.0,
|
||||
othervehiclevelocity, velocity,
|
||||
othervehicle->TotalMass, TotalMass,
|
||||
( coupler.beta + othercoupler.beta ) / 2.0,
|
||||
VirtualCoupling )
|
||||
/ ( dt );
|
||||
break; // czemu tu jest +0.01??
|
||||
break;
|
||||
}
|
||||
AccS = AccS + (V - Vprev) / dt; // korekta przyspieszenia o siły wynikające ze zderzeń?
|
||||
coupler.Connected->AccS += (coupler.Connected->V - VprevC) / dt;
|
||||
if ((coupler.Dist > 0) && (!VirtualCoupling))
|
||||
if (FuzzyLogic(abs(CCF), 5.0 * (coupler.FmaxC + 1.0), p_coupldmg))
|
||||
{ //! zerwanie sprzegu
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if ((coupler.CouplingFlag & ctrain_pneumatic) == ctrain_pneumatic)
|
||||
AlarmChainFlag = true; // hamowanie nagle - zerwanie przewodow hamulcowych
|
||||
auto &coupler { Couplers[ End ] };
|
||||
|
||||
if( ( coupler.CouplingFlag & ctrain_pneumatic ) == ctrain_pneumatic ) {
|
||||
// hamowanie nagle - zerwanie przewodow hamulcowych
|
||||
AlarmChainFlag = true;
|
||||
}
|
||||
|
||||
coupler.CouplingFlag = 0;
|
||||
|
||||
switch (CouplerN) // wyzerowanie flag podlaczenia ale ciagle sa wirtualnie polaczone
|
||||
{
|
||||
case 0:
|
||||
coupler.Connected->Couplers[1].CouplingFlag = 0;
|
||||
break;
|
||||
case 1:
|
||||
coupler.Connected->Couplers[0].CouplingFlag = 0;
|
||||
if( coupler.Connected != nullptr ) {
|
||||
switch( End ) {
|
||||
// break connection with other vehicle, if there's any
|
||||
case 0: {
|
||||
coupler.Connected->Couplers[ end::rear ].CouplingFlag = 0;
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
coupler.Connected->Couplers[ end::front ].CouplingFlag = 0;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
TTrackParam &Track, TTractionParam &ElectricTraction,
|
||||
const TLocation &NewLoc, TRotation &NewRot)
|
||||
TLocation const &NewLoc, TRotation const &NewRot)
|
||||
{
|
||||
const double Vepsilon = 1e-5;
|
||||
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
|
||||
Loc = NewLoc;
|
||||
Rot = NewRot;
|
||||
NewRot.Rx = 0;
|
||||
NewRot.Ry = 0;
|
||||
NewRot.Rz = 0;
|
||||
|
||||
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,
|
||||
TTrackParam &Track, const TLocation &NewLoc,
|
||||
TRotation &NewRot)
|
||||
TTrackParam &Track, TLocation const &NewLoc,
|
||||
TRotation const &NewRot)
|
||||
{
|
||||
int b;
|
||||
// T_MoverParameters::FastComputeMovement(dt, Shape, Track, NewLoc, NewRot);
|
||||
|
||||
Loc = NewLoc;
|
||||
Rot = NewRot;
|
||||
NewRot.Rx = 0.0;
|
||||
NewRot.Ry = 0.0;
|
||||
NewRot.Rz = 0.0;
|
||||
|
||||
if (dL == 0) // oblicz przesuniecie
|
||||
{
|
||||
@@ -1716,7 +1782,7 @@ void TMoverParameters::OilPumpCheck( double const Timestep ) {
|
||||
OilPump.pressure =
|
||||
std::max<float>(
|
||||
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 );
|
||||
}
|
||||
@@ -4129,6 +4195,11 @@ void TMoverParameters::ComputeTotalForce(double dt) {
|
||||
|
||||
// juz zoptymalizowane:
|
||||
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);
|
||||
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 const othervehiclemove { ( othervehicle->dMoveLen * DirPatch( End, otherend ) ) };
|
||||
auto const initialdistance { Neighbours[ End ].distance }; // odległość od sprzęgu sąsiada
|
||||
auto const distancedelta { (
|
||||
End == end::front ?
|
||||
othervehiclemove - dMoveLen :
|
||||
dMoveLen - othervehiclemove ) };
|
||||
auto const initialdistance { Neighbours[ End ].distance }; // odległość od sprzęgu sąsiada
|
||||
|
||||
auto const newdistance =
|
||||
initialdistance
|
||||
+ 10.0 * distancedelta;
|
||||
auto const newdistance { initialdistance + 10.0 * distancedelta };
|
||||
|
||||
auto const dV { V - ( othervehicle->V * DirPatch( End, otherend ) ) };
|
||||
auto const absdV { std::abs( dV ) };
|
||||
@@ -4456,11 +4525,15 @@ double TMoverParameters::CouplerForce( int const End, double dt ) {
|
||||
}
|
||||
|
||||
coupler.CheckCollision = false;
|
||||
coupler.Dist = 0.0;
|
||||
|
||||
double CF { 0.0 };
|
||||
|
||||
if( ( coupler.CouplingFlag != coupling::faux )
|
||||
|| ( initialdistance < 0 ) ) {
|
||||
|
||||
coupler.Dist = clamp( newdistance, -coupler.DmaxB, coupler.DmaxC );
|
||||
|
||||
double BetaAvg = 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;
|
||||
}
|
||||
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 ) {
|
||||
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;
|
||||
}
|
||||
// liczenie sily ze sprezystosci sprzegu
|
||||
if( coupler.Dist > ( coupler.DmaxC + othercoupler.DmaxC ) ) {
|
||||
if( newdistance > ( coupler.DmaxC + othercoupler.DmaxC ) ) {
|
||||
// zderzenie
|
||||
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 ) {
|
||||
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;
|
||||
}
|
||||
// liczenie sily ze sprezystosci zderzaka
|
||||
if( -coupler.Dist > ( coupler.DmaxB + othercoupler.DmaxB ) ) {
|
||||
if( -newdistance > ( coupler.DmaxB + othercoupler.DmaxB ) ) {
|
||||
// zderzenie
|
||||
coupler.CheckCollision = true;
|
||||
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_df] = eimv[eimv_ks] * eimc[eimc_s_dfmax];
|
||||
eimv[eimv_fp] = DirAbsolute * enrot * eimc[eimc_s_p] +
|
||||
eimv[eimv_df]; // do przemyslenia dzialanie pp z tmpV
|
||||
eimv[eimv_fp] = DirAbsolute * enrot * eimc[eimc_s_p] + 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_pole]:=eimv[eimv_U]/(eimv[eimv_fp]*eimc[eimc_s_cfu]);
|
||||
if ((abs(eimv[eimv_fp]) <= eimv[eimv_fkr]))
|
||||
eimv[eimv_pole] = eimc[eimc_f_cfu] / eimc[eimc_s_cfu];
|
||||
else
|
||||
eimv[eimv_pole] =
|
||||
eimv[eimv_Uzsmax] / eimc[eimc_s_cfu] / abs(eimv[eimv_fp]);
|
||||
eimv[eimv_pole] = 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_Ic] = (eimv[eimv_fp] - DirAbsolute * enrot * eimc[eimc_s_p]) *
|
||||
eimc[eimc_s_dfic] * eimv[eimv_pole];
|
||||
eimv[eimv_Ic] = (eimv[eimv_fp] - DirAbsolute * enrot * eimc[eimc_s_p]) * eimc[eimc_s_dfic] * eimv[eimv_pole];
|
||||
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_Ipoj] = (eimv[eimv_Ic] * NPoweredAxles * eimv[eimv_U]) /
|
||||
(Voltage - eimc[eimc_f_DU]) +
|
||||
eimc[eimc_f_I0];
|
||||
eimv[eimv_Pm] =
|
||||
ActiveDir * eimv[eimv_M] * NPoweredAxles * enrot * Pirazy2 / 1000;
|
||||
eimv[eimv_Ipoj] = (eimv[eimv_Ic] * NPoweredAxles * eimv[eimv_U]) / (Voltage - eimc[eimc_f_DU]) + 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_eta] = eimv[eimv_Pm] / eimv[eimv_Pe];
|
||||
|
||||
@@ -5441,7 +5521,7 @@ double TMoverParameters::TractionForce( double dt ) {
|
||||
|
||||
if( ( RlistSize > 0 )
|
||||
&& ( ( std::abs( eimv[ eimv_If ] ) > 1.0 )
|
||||
|| ( tmpV > 0.1 ) ) ) {
|
||||
&& ( tmpV > 0.1 ) ) ) {
|
||||
|
||||
int i = 0;
|
||||
while( ( i < RlistSize - 1 )
|
||||
|
||||
12
Train.cpp
12
Train.cpp
@@ -500,7 +500,7 @@ dictionary_source *TTrain::GetTrainState() {
|
||||
// induction motor state data
|
||||
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 *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" };
|
||||
for( int j = 0; j < 10; ++j )
|
||||
dict->insert( ( "eimp_t_" + std::string( TXTT[ j ] ) ), fEIMParams[ 0 ][ j ] );
|
||||
@@ -588,6 +588,7 @@ TTrain::get_state() const {
|
||||
btLampkaNadmWent.GetValue(),
|
||||
btLampkaWysRozr.GetValue(),
|
||||
btLampkaOgrzewanieSkladu.GetValue(),
|
||||
static_cast<std::uint8_t>( iCabn ),
|
||||
btHaslerBrakes.GetValue(),
|
||||
btHaslerCurrent.GetValue(),
|
||||
( 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->BrakePress ),
|
||||
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++;
|
||||
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][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][6] = p->MoverParameters->dizel_heat.Twy;
|
||||
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->
|
||||
bMains[in] = p->MoverParameters->Mains;
|
||||
fCntVol[in] = p->MoverParameters->BatteryVoltage;
|
||||
|
||||
10
Train.h
10
Train.h
@@ -69,8 +69,10 @@ public:
|
||||
find( TSubModel const *Control ) const;
|
||||
};
|
||||
|
||||
class TTrain
|
||||
{
|
||||
class TTrain {
|
||||
|
||||
friend class drivingaid_panel;
|
||||
|
||||
public:
|
||||
// types
|
||||
struct state_t {
|
||||
@@ -88,6 +90,7 @@ class TTrain
|
||||
std::uint8_t ventilator_overload;
|
||||
std::uint8_t motor_overload_threshold;
|
||||
std::uint8_t train_heating;
|
||||
std::uint8_t cab;
|
||||
std::uint8_t recorder_braking;
|
||||
std::uint8_t recorder_power;
|
||||
std::uint8_t alerter_sound;
|
||||
@@ -98,6 +101,7 @@ class TTrain
|
||||
float brake_pressure;
|
||||
float hv_voltage;
|
||||
std::array<float, 3> hv_current;
|
||||
float lv_voltage;
|
||||
};
|
||||
|
||||
// methods
|
||||
@@ -626,7 +630,7 @@ public: // reszta może by?publiczna
|
||||
*/
|
||||
// McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc
|
||||
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
|
||||
Math3D::vector3 pMechSittingPosition; // ABu 180404
|
||||
Math3D::vector3 MirrorPosition( bool lewe );
|
||||
|
||||
@@ -20,6 +20,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "Camera.h"
|
||||
#include "mtable.h"
|
||||
#include "Train.h"
|
||||
#include "Button.h"
|
||||
#include "Driver.h"
|
||||
#include "AnimModel.h"
|
||||
#include "DynObj.h"
|
||||
@@ -135,12 +136,14 @@ drivingaid_panel::update() {
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string textline =
|
||||
( true == TestFlag( mover->SecuritySystem.Status, s_aware ) ?
|
||||
std::string textline = (
|
||||
( ( true == TestFlag( mover->SecuritySystem.Status, s_aware ) )
|
||||
&& ( train != nullptr )
|
||||
&& ( train->fBlinkTimer > 0 ) ) ?
|
||||
locale::strings[ locale::string::driver_aid_alerter ] :
|
||||
" " );
|
||||
textline +=
|
||||
( true == TestFlag( mover->SecuritySystem.Status, s_active ) ?
|
||||
textline += (
|
||||
( true == TestFlag( mover->SecuritySystem.Status, s_active ) ) ?
|
||||
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 += "\nLight level: " + to_string( Global.fLuminance, 3 );
|
||||
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";
|
||||
|
||||
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
|
||||
// convert spherical coordinates to opengl coordinates
|
||||
auto const launchvector { glm::vec3(
|
||||
std::sin( polarangle ) * std::sin( azimuthalangle ),
|
||||
std::sin( polarangle ) * std::sin( azimuthalangle ) * -1,
|
||||
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 ] ) ) };
|
||||
|
||||
Particle.velocity = launchvector * launchvelocity;
|
||||
|
||||
@@ -194,13 +194,17 @@ world_environment::update_wind() {
|
||||
|
||||
m_wind.change_time -= timedelta;
|
||||
if( m_wind.change_time < 0 ) {
|
||||
m_wind.change_time = Random( 5, 30 );
|
||||
m_wind.velocity_change = Random( -1, 1 );
|
||||
if( Random() < 0.2 ) {
|
||||
m_wind.change_time = Random( 5, 15 );
|
||||
m_wind.velocity_change = Random( -0.2, 0.2 );
|
||||
if( Random() < 0.05 ) {
|
||||
// changes in wind direction should be less frequent than changes in wind speed
|
||||
// TBD, TODO: configuration-driven direction change frequency
|
||||
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
|
||||
m_wind.azimuth = clamp_circular( m_wind.azimuth + m_wind.azimuth_change * timedelta );
|
||||
@@ -213,9 +217,9 @@ world_environment::update_wind() {
|
||||
m_wind.vector =
|
||||
std::max( 0.f, m_wind.velocity )
|
||||
* glm::vec3(
|
||||
std::sin( polarangle ) * std::sin( azimuthalangle ),
|
||||
std::sin( polarangle ) * std::sin( azimuthalangle ) * -1,
|
||||
std::cos( polarangle ),
|
||||
std::sin( polarangle ) * std::cos( azimuthalangle ) * -1 );
|
||||
std::sin( polarangle ) * std::cos( azimuthalangle ) );
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -40,6 +40,9 @@ public:
|
||||
glm::vec3 const &
|
||||
wind() const {
|
||||
return m_wind.vector; }
|
||||
float const &
|
||||
wind_azimuth() const {
|
||||
return m_wind.azimuth; }
|
||||
|
||||
private:
|
||||
// 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
|
||||
// TODO: exchange driven by station parameters and time of the day
|
||||
auto unloadcount = static_cast<int>(
|
||||
TestFlag( parameters.DamageFlag, dtrain_out ) ? parameters.LoadAmount :
|
||||
laststop ? parameters.LoadAmount :
|
||||
firststop ? 0 :
|
||||
std::min<float>(
|
||||
parameters.LoadAmount,
|
||||
Random( parameters.MaxLoad * 0.15f * stationsizemodifier ) ) );
|
||||
auto loadcount = static_cast<int>(
|
||||
laststop ?
|
||||
0 :
|
||||
TestFlag( parameters.DamageFlag, dtrain_out ) ? 0 :
|
||||
laststop ? 0 :
|
||||
Random( parameters.MaxLoad * 0.15f * stationsizemodifier ) );
|
||||
if( true == firststop ) {
|
||||
// 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 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 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 {
|
||||
//byte 0
|
||||
@@ -271,7 +277,8 @@ void uart_input::poll()
|
||||
| trainstate.compressor_overload << 6),
|
||||
//byte 6
|
||||
(uint8_t)(
|
||||
trainstate.recorder_braking << 3
|
||||
m_trainstatecab << 2
|
||||
| trainstate.recorder_braking << 3
|
||||
| trainstate.recorder_power << 4
|
||||
| trainstate.radio_stop <<5
|
||||
| trainstate.alerter_sound << 7),
|
||||
@@ -289,8 +296,10 @@ void uart_input::poll()
|
||||
SPLIT_INT16(current2),
|
||||
//byte 19-20
|
||||
SPLIT_INT16(current3),
|
||||
//byte 21-30
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
//byte 21-22
|
||||
SPLIT_INT16(lv_voltage),
|
||||
//byte 23-30
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
if (conf.debug)
|
||||
|
||||
3
uart.h
3
uart.h
@@ -27,6 +27,8 @@ public:
|
||||
float hvuart = 65535.0f;
|
||||
float currentmax = 10000.0f;
|
||||
float currentuart = 65535.0f;
|
||||
float lvmax = 150.0f;
|
||||
float lvuart = 65535.0f;
|
||||
|
||||
bool mainenable = true;
|
||||
bool scndenable = true;
|
||||
@@ -66,4 +68,5 @@ private:
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> last_update;
|
||||
conf_t conf;
|
||||
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