16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 11:39:19 +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:
tmj-fstate
2019-09-02 19:18:44 +02:00
parent 269e271f01
commit 68a45db21a
16 changed files with 285 additions and 147 deletions

View File

@@ -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,
VirtualCoupling)
/ (dt);
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,
VirtualCoupling)
/ (dt);
break; // czemu tu jest +0.01??
othervehiclevelocity, velocity,
othervehicle->TotalMass, TotalMass,
( coupler.beta + othercoupler.beta ) / 2.0,
VirtualCoupling )
/ ( dt );
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
if (SetFlag(DamageFlag, dtrain_coupling))
EventFlag = true;
default: {
break;
}
}
if ((coupler.CouplingFlag & ctrain_pneumatic) == ctrain_pneumatic)
AlarmChainFlag = true; // hamowanie nagle - zerwanie przewodow hamulcowych
coupler.CouplingFlag = 0;
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 );
}
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;
break;
}
WriteLog( "Bad driving: " + Name + " broke a coupler" );
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;
auto &coupler { Couplers[ End ] };
if( ( coupler.CouplingFlag & ctrain_pneumatic ) == ctrain_pneumatic ) {
// hamowanie nagle - zerwanie przewodow hamulcowych
AlarmChainFlag = true;
}
coupler.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 );
}
}
else {
coupler.stretch_duration = 0.f;
}
}
if( coupler.Dist < 0 ) {
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 )