build 170908. minor refactoring and diagnostics enhancements, virtual coupling fix, support for pantograph compressor submodels

This commit is contained in:
tmj-fstate
2017-09-09 00:55:16 +02:00
parent 53ad41afa0
commit 435dc24d3e
13 changed files with 257 additions and 217 deletions

View File

@@ -46,12 +46,12 @@ ProjectEventOnTrack( TEvent const *Event, TTrack const *Track, double const Dire
( 1.0 - nearestpoint ) * segment->GetLength() ); // measure from point2
};
double GetDistanceToEvent(TTrack* track, TEvent* event, double scan_dir, double start_dist, int iter = 0, bool back = false)
double GetDistanceToEvent(TTrack const *track, TEvent const *event, double scan_dir, double start_dist, int iter = 0, bool back = false)
{
if( track == nullptr ) { return start_dist; }
auto const segment = track->CurrentSegment();
vector3 const pos_event = event->PositionGet();
auto const pos_event = event->PositionGet();
double len1, len2;
double sd = scan_dir;
double seg_len = scan_dir > 0 ? 0.0 : 1.0;
@@ -63,7 +63,7 @@ double GetDistanceToEvent(TTrack* track, TEvent* event, double scan_dir, double
len1 = len2;
seg_len += scan_dir > 0 ? dzielnik : -dzielnik;
len2 = (pos_event - segment->FastGetPoint(seg_len)).LengthSquared();
krok++;
++krok;
} while ((len1 > len2) && (seg_len >= dzielnik && (seg_len <= (1 - dzielnik))));
//trzeba sprawdzić czy seg_len nie osiągnął skrajnych wartości, bo wtedy
// trzeba sprawdzić tor obok
@@ -71,7 +71,7 @@ double GetDistanceToEvent(TTrack* track, TEvent* event, double scan_dir, double
sd = -sd; // jeśli tylko jeden krok tzn, że event przy poprzednim sprawdzaym torze
if (((seg_len <= dzielnik) || (seg_len > (1 - dzielnik))) && (iter < 3))
{ // przejście na inny tor
track = track->Neightbour(int(sd), sd);
track = track->Connected(int(sd), sd);
start_dist += (1 == krok) ? 0 : back ? -segment->GetLength() : segment->GetLength();
return GetDistanceToEvent(track, event, sd, start_dist, ++iter, 1 == krok ? true : false);
}
@@ -616,7 +616,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
fCurrentDistance += fTrackLength; // doliczenie kolejnego odcinka do przeskanowanej długości
tLast = pTrack; // odhaczenie, że sprawdzony
fLastVel = pTrack->VelocityGet(); // prędkość na poprzednio sprawdzonym odcinku
pTrack = pTrack->Neightbour(
pTrack = pTrack->Connected(
( pTrack->eType == tt_Cross ?
(sSpeedTable[iLast].iFlags >> 28) :
static_cast<int>(fLastDir) ),

View File

@@ -1262,71 +1262,65 @@ int TDynamicObject::Dettach(int dir)
.CouplingFlag; // sprzęg po rozłączaniu (czego się nie da odpiąć
}
void TDynamicObject::CouplersDettach(double MinDist, int MyScanDir)
{ // funkcja rozłączajaca podłączone sprzęgi,
// jeśli odległość przekracza (MinDist)
void TDynamicObject::CouplersDettach(double MinDist, int MyScanDir) {
// funkcja rozłączajaca podłączone sprzęgi, jeśli odległość przekracza (MinDist)
// MinDist - dystans minimalny, dla ktorego mozna rozłączać
if (MyScanDir > 0)
{
if (PrevConnected) // pojazd od strony sprzęgu 0
{
if (MoverParameters->Couplers[0].CoupleDist > MinDist) {
// sprzęgi wirtualne zawsze przekraczają
if ((PrevConnectedNo ? PrevConnected->NextConnected :
PrevConnected->PrevConnected) == this)
{ // Ra: nie rozłączamy znalezionego, jeżeli nie do nas
// podłączony (może jechać w
// innym kierunku)
PrevConnected->MoverParameters->Couplers[PrevConnectedNo].Connected = NULL;
if (PrevConnectedNo == 0)
{
PrevConnected->PrevConnectedNo = 2; // sprzęg 0 nie podłączony
PrevConnected->PrevConnected = NULL;
}
else if (PrevConnectedNo == 1)
{
PrevConnected->NextConnectedNo = 2; // sprzęg 1 nie podłączony
PrevConnected->NextConnected = NULL;
}
if (MyScanDir > 0) {
// pojazd od strony sprzęgu 0
if( ( PrevConnected != nullptr )
&& ( MoverParameters->Couplers[ TMoverParameters::side::front ].CoupleDist > MinDist ) ) {
// sprzęgi wirtualne zawsze przekraczają
if( ( PrevConnectedNo == TMoverParameters::side::front ?
PrevConnected->PrevConnected :
PrevConnected->NextConnected )
== this ) {
// Ra: nie rozłączamy znalezionego, jeżeli nie do nas podłączony
// (może jechać w innym kierunku)
PrevConnected->MoverParameters->Couplers[PrevConnectedNo].Connected = nullptr;
if( PrevConnectedNo == TMoverParameters::side::front ) {
// sprzęg 0 nie podłączony
PrevConnected->PrevConnectedNo = 2;
PrevConnected->PrevConnected = nullptr;
}
else if( PrevConnectedNo == TMoverParameters::side::rear ) {
// sprzęg 1 nie podłączony
PrevConnected->NextConnectedNo = 2;
PrevConnected->NextConnected = nullptr;
}
// za to zawsze odłączamy siebie
PrevConnected = NULL;
PrevConnectedNo = 2; // sprzęg 0 nie podłączony
MoverParameters->Couplers[0].Connected = nullptr;
}
// za to zawsze odłączamy siebie
PrevConnected = nullptr;
PrevConnectedNo = 2; // sprzęg 0 nie podłączony
MoverParameters->Couplers[ TMoverParameters::side::front ].Connected = nullptr;
}
}
else
{
if (NextConnected) // pojazd od strony sprzęgu 1
{
if (MoverParameters->Couplers[1].CoupleDist > MinDist) {
// sprzęgi wirtualne zawsze przekraczają
if ((NextConnectedNo ? NextConnected->NextConnected :
NextConnected->PrevConnected) == this)
{ // Ra: nie rozłączamy znalezionego, jeżeli nie do nas
// podłączony (może jechać w
// innym kierunku)
NextConnected->MoverParameters->Couplers[NextConnectedNo].Connected = NULL;
if (NextConnectedNo == 0)
{
NextConnected->PrevConnectedNo = 2; // sprzęg 0 nie podłączony
NextConnected->PrevConnected = NULL;
}
else if (NextConnectedNo == 1)
{
NextConnected->NextConnectedNo = 2; // sprzęg 1 nie podłączony
NextConnected->NextConnected = NULL;
}
else {
// pojazd od strony sprzęgu 1
if( ( NextConnected != nullptr )
&& ( MoverParameters->Couplers[ TMoverParameters::side::rear ].CoupleDist > MinDist ) ) {
// sprzęgi wirtualne zawsze przekraczają
if( ( NextConnectedNo == TMoverParameters::side::front ?
NextConnected->PrevConnected :
NextConnected->NextConnected )
== this) {
// Ra: nie rozłączamy znalezionego, jeżeli nie do nas podłączony
// (może jechać w innym kierunku)
NextConnected->MoverParameters->Couplers[ NextConnectedNo ].Connected = nullptr;
if( NextConnectedNo == TMoverParameters::side::front ) {
// sprzęg 0 nie podłączony
NextConnected->PrevConnectedNo = 2;
NextConnected->PrevConnected = nullptr;
}
else if( NextConnectedNo == TMoverParameters::side::rear ) {
// sprzęg 1 nie podłączony
NextConnected->NextConnectedNo = 2;
NextConnected->NextConnected = nullptr;
}
NextConnected = NULL;
NextConnectedNo = 2; // sprzęg 1 nie podłączony
MoverParameters->Couplers[1].Connected = nullptr;
}
// za to zawsze odłączamy siebie
NextConnected = nullptr;
NextConnectedNo = 2; // sprzęg 1 nie podłączony
MoverParameters->Couplers[1].Connected = nullptr;
}
}
}
@@ -1428,6 +1422,18 @@ void TDynamicObject::ABuScanObjects( int Direction, double Distance )
if( foundobject->MoverParameters->Couplers[ foundcoupler ].CouplingFlag == coupling::faux ) {
// Ra: wpinamy się wirtualnym tylko jeśli znaleziony ma wirtualny sprzęg
if( ( foundcoupler == TMoverParameters::side::front ?
foundobject->PrevConnected :
foundobject->NextConnected )
!= this ) {
// but first break existing connection of the target,
// otherwise we risk leaving the target's connected vehicle with active one-side connection
foundobject->CouplersDettach(
1.0,
( foundcoupler == TMoverParameters::side::front ?
1 :
-1 ) );
}
foundobject->MoverParameters->Attach( foundcoupler, mycoupler, this->MoverParameters, coupling::faux );
if( foundcoupler == TMoverParameters::side::front ) {
@@ -2577,15 +2583,19 @@ bool TDynamicObject::Update(double dt, double dt1)
tp.CategoryFlag = MyTrack->iCategoryFlag & 15;
tp.DamageFlag = MyTrack->iDamageFlag;
tp.QualityFlag = MyTrack->iQualityFlag;
if ((MoverParameters->Couplers[0].CouplingFlag > 0) &&
(MoverParameters->Couplers[1].CouplingFlag > 0))
{
// couplers
if( ( MoverParameters->Couplers[ 0 ].CouplingFlag != coupling::faux )
&& ( MoverParameters->Couplers[ 1 ].CouplingFlag != coupling::faux ) ) {
MoverParameters->InsideConsist = true;
}
else
{
else {
MoverParameters->InsideConsist = false;
}
//
// napiecie sieci trakcyjnej
// Ra 15-01: przeliczenie poboru prądu powinno być robione wcześniej, żeby na
// tym etapie były

120
Event.cpp
View File

@@ -140,10 +140,7 @@ void TEvent::Conditions(cParser *parser, std::string s)
void TEvent::Load(cParser *parser, vector3 *org)
{
int i;
int ti;
std::string token;
//string str;
bEnabled = true; // zmieniane na false dla eventów używanych do skanowania sygnałów
@@ -247,47 +244,47 @@ void TEvent::Load(cParser *parser, vector3 *org)
*parser >> token;
Conditions(parser, token); // sprawdzanie warunków
break;
case tp_CopyValues:
Params[9].asText = NULL;
case tp_CopyValues: {
Params[9].asText = nullptr;
iFlags = update_memstring | update_memval1 | update_memval2; // normalanie trzy
i = 0;
int paramidx { 0 };
parser->getTokens();
*parser >> token; // nazwa drugiej komórki (źródłowej)
while (token.compare("endevent") != 0)
{
switch (++i)
while (token.compare("endevent") != 0) {
switch (++paramidx)
{ // znaczenie kolejnych parametrów
case 1: // nazwa drugiej komórki (źródłowej)
Params[9].asText = new char[token.size() + 1]; // usuwane i zamieniane na wskaźnik
strcpy(Params[9].asText, token.c_str());
break;
case 2: // maska wartości
iFlags = stol_def(token,
(update_memstring | update_memval1 | update_memval2));
iFlags = stol_def(token, (update_memstring | update_memval1 | update_memval2));
break;
}
parser->getTokens();
*parser >> token;
}
break;
case tp_WhoIs:
}
case tp_WhoIs: {
iFlags = update_memstring | update_memval1 | update_memval2; // normalanie trzy
i = 0;
int paramidx { 0 };
parser->getTokens();
*parser >> token; // nazwa drugiej komórki (źródłowej)
while (token.compare("endevent") != 0)
{
switch (++i)
{ // znaczenie kolejnych parametrów
case 1: // maska wartości
iFlags = stol_def(token,
(update_memstring | update_memval1 | update_memval2));
break;
while( token.compare( "endevent" ) != 0 ) {
switch( ++paramidx ) { // znaczenie kolejnych parametrów
case 1: // maska wartości
iFlags = stol_def( token, ( update_memstring | update_memval1 | update_memval2 ) );
break;
default:
break;
}
parser->getTokens();
*parser >> token;
}
break;
}
case tp_GetValues:
case tp_LogValues:
parser->getTokens(); //"endevent"
@@ -384,25 +381,27 @@ void TEvent::Load(cParser *parser, vector3 *org)
parser->getTokens();
*parser >> token;
break;
case tp_Lights:
i = 0;
do
{
case tp_Lights: {
int paramidx { 0 };
do {
parser->getTokens();
*parser >> token;
if (token.compare("endevent") != 0)
{
// str = AnsiString(token.c_str());
if (i < 8)
Params[i].asdouble = atof(token.c_str()); // teraz może mieć ułamek
i++;
if( token.compare( "endevent" ) != 0 ) {
if( paramidx < 8 ) {
Params[ paramidx ].asdouble = atof( token.c_str() ); // teraz może mieć ułamek
++paramidx;
}
else {
ErrorLog( "Bad event: lights event \"" + asName + "\" with more than 8 parameters" );
}
}
} while (token.compare("endevent") != 0);
} while( token.compare( "endevent" ) != 0 );
break;
}
case tp_Visible: // zmiana wyświetlania obiektu
parser->getTokens();
*parser >> token;
// str = AnsiString(token.c_str());
Params[0].asInt = atoi(token.c_str());
parser->getTokens();
*parser >> token;
@@ -410,7 +409,6 @@ void TEvent::Load(cParser *parser, vector3 *org)
case tp_Velocity:
parser->getTokens();
*parser >> token;
// str = AnsiString(token.c_str());
Params[0].asdouble = atof(token.c_str()) * 0.28;
parser->getTokens();
*parser >> token;
@@ -544,38 +542,46 @@ void TEvent::Load(cParser *parser, vector3 *org)
parser->getTokens();
*parser >> token;
break;
case tp_Multiple:
i = 0;
ti = 0; // flaga dla else
case tp_Multiple: {
int paramidx { 0 };
bool ti { false }; // flaga dla else
parser->getTokens();
*parser >> token;
// str = AnsiString(token.c_str());
while (token != "endevent" && token != "condition" &&
token != "randomdelay")
{
if ((token.substr(0, 5) != "none_") ? (i < 8) : false)
{ // eventy rozpoczynające się od "none_" są ignorowane
if (token != "else")
{
Params[i].asText = new char[token.size() + 1];
strcpy(Params[i].asText, token.c_str());
if (ti)
iFlags |= conditional_else << i; // oflagowanie dla eventów "else"
i++;
while( ( token != "endevent" )
&& ( token != "condition" )
&& ( token != "randomdelay" ) ) {
if( token != "else" ) {
if( token.substr( 0, 5 ) != "none_" ) {
// eventy rozpoczynające się od "none_" są ignorowane
if( paramidx < 8 ) {
Params[ paramidx ].asText = new char[ token.size() + 1 ];
strcpy( Params[ paramidx ].asText, token.c_str() );
if( ti ) {
// oflagowanie dla eventów "else"
iFlags |= conditional_else << paramidx;
}
++paramidx;
}
else {
ErrorLog( "Bad event: multi-event \"" + asName + "\" with more than 8 events; discarding link to event \"" + token + "\"" );
}
}
else {
WriteLog( "Multi-event \"" + asName + "\" ignored link to event \"" + token + "\"" );
}
else
ti = !ti; // zmiana flagi dla słowa "else"
}
else if (i >= 8)
ErrorLog("Bad event: \"" + token + "\" ignored in multiple \"" + asName + "\"!");
else
WriteLog("Event \"" + token + "\" ignored in multiple \"" + asName + "\"!");
else {
// zmiana flagi dla słowa "else"
ti = !ti;
}
parser->getTokens();
*parser >> token;
// str = AnsiString(token.c_str());
}
Conditions(parser, token); // sprawdzanie warunków
break;
}
case tp_Voltage: // zmiana napięcia w zasilaczu (TractionPowerSource)
case tp_Friction: // zmiana przyczepnosci na scenerii
parser->getTokens();

View File

@@ -2175,11 +2175,11 @@ bool TGround::Init(std::string File)
{ // możliwość przedefiniowania parametrów w scenerii
Global::ConfigParse(parser); // parsowanie dodatkowych ustawień
}
else if (str != "")
{ // pomijanie od nierozpoznanej komendy do jej zakończenia
if ((token.length() > 2) && (atof(token.c_str()) == 0.0))
{ // jeśli nie liczba, to spróbować pominąć komendę
WriteLog("Unrecognized command: " + str);
else if (str != "") {
// pomijanie od nierozpoznanej komendy do jej zakończenia
if ((token.length() > 2) && (atof(token.c_str()) == 0.0)) {
// jeśli nie liczba, to spróbować pominąć komendę
WriteLog( "Unrecognized command: \"" + str + "\" encountered in file \"" + parser.Name() + "\" (line " + std::to_string( parser.Line() - 1 ) + ")" );
str = "end" + str;
do
{
@@ -2188,8 +2188,10 @@ bool TGround::Init(std::string File)
parser >> token;
} while ((token != "") && (token.compare(str.c_str()) != 0));
}
else // jak liczba to na pewno błąd
Error("Unrecognized command: " + str);
else {
// jak liczba to na pewno błąd
ErrorLog( "Unrecognized command: \"" + str + "\" encountered in file \"" + parser.Name() + "\" (line " + std::to_string( parser.Line() - 1 ) + ")" );
}
}
token = "";

View File

@@ -813,7 +813,6 @@ public:
voltage
};
#endif
int ScanCounter = 0; /*pomocnicze do skanowania sprzegow*/
bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/
int SoundFlag = 0; /*!o patrz stale sound_ */
double DistCounter = 0.0; /*! licznik kilometrow */

View File

@@ -473,7 +473,7 @@ bool TMoverParameters::Attach(int ConnectNo, int ConnectToNr, TMoverParameters *
coupler.Connected = ConnectTo; // tak podpiąć (do siebie) zawsze można, najwyżej będzie wirtualny
CouplerDist( ConnectNo ); // przeliczenie odległości pomiędzy sprzęgami
if (CouplingType == ctrain_virtual)
if (CouplingType == coupling::faux)
return false; // wirtualny więcej nic nie robi
auto &othercoupler = ConnectTo->Couplers[ coupler.ConnectedNr ];
@@ -555,21 +555,29 @@ bool TMoverParameters::Dettach(int ConnectNo)
return false; // jeszcze nie rozłączony
};
void TMoverParameters::SetCoupleDist()
{ // przeliczenie odległości sprzęgów
if (Couplers[0].Connected)
{
CouplerDist(0);
if (CategoryFlag & 2)
{ // Ra: dla samochodów zderzanie kul to za mało
// przeliczenie odległości sprzęgów
void TMoverParameters::SetCoupleDist() {
/*
double const MaxDist = 100.0; // 2x average max proximity distance. TODO: rearrange ito something more elegant
*/
for( int coupleridx = 0; coupleridx <= 1; ++coupleridx ) {
if( Couplers[ coupleridx ].Connected == nullptr ) { continue; }
CouplerDist( coupleridx );
if( CategoryFlag & 2 ) {
// Ra: dla samochodów zderzanie kul to za mało
// NOTE: whatever calculation was supposed to be here, ain't
}
}
if (Couplers[1].Connected)
{
CouplerDist(1);
if (CategoryFlag & 2)
{ // Ra: dla samochodów zderzanie kul to za mało
/*
if( ( Couplers[ coupleridx ].CouplingFlag == coupling::faux )
&& ( Couplers[ coupleridx ].CoupleDist > MaxDist ) ) {
// zerwij kontrolnie wirtualny sprzeg
// Connected.Couplers[CNext].Connected:=nil; //Ra: ten podłączony niekoniecznie jest wirtualny
Couplers[ coupleridx ].Connected = nullptr;
Couplers[ coupleridx ].ConnectedNr = 2;
}
*/
}
};
@@ -3725,14 +3733,12 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer)
else {
Voltage = 0;
}
//if (Mains && /*(abs(CabNo) < 2) &&*/ (
// EngineType == ElectricInductionMotor)) // potem ulepszyc! pantogtrafy!
// Voltage = RunningTraction.TractionVoltage;
if (Power > 0)
FTrain = TractionForce(dt);
else
FTrain = 0;
Fb = BrakeForce(RunningTrack);
Fwheels = FTrain - Fb * Sign(V);
if( ( Vel > 0.001 ) // crude trap, to prevent braked stationary vehicles from passing fb > mass * adhesive test
@@ -3966,7 +3972,7 @@ double TMoverParameters::Adhesive(double staticfriction)
// WriteLog(FloatToStr(adhesive)); // tutaj jest na poziomie 0.2 - 0.3
return adhesion;
*/
/* //wersja druga
//wersja druga
if( true == SlippingWheels ) {
if( true == SandDose ) { adhesion = 0.48; }
@@ -3977,12 +3983,15 @@ double TMoverParameters::Adhesive(double staticfriction)
if( true == SandDose ) { adhesion = std::max( staticfriction * ( 100.0 + Vel ) / ( 50.0 + Vel ) * 1.1, 0.48 ); }
else { adhesion = staticfriction * ( 100.0 + Vel ) / ( 50.0 + Vel ); }
}
adhesion *= ( 11.0 - 2 * Random() ) / 10.0; */
// adhesion *= ( 0.9 + 0.2 * Random() );
/*
//wersja3 by youBy - uwzględnia naturalne mikropoślizgi i wpływ piasecznicy, usuwa losowość z pojazdu
double Vwheels = nrot * M_PI * WheelDiameter; // predkosc liniowa koła wynikająca z obrotowej
double deltaV = V - Vwheels; //poślizg - różnica prędkości w punkcie styku koła i szyny
deltaV = std::max(0.0, std::abs(deltaV) - 0.25); //mikropoślizgi do ok. 0,25 m/s nie zrywają przyczepności
adhesion = staticfriction * (28 + Vwheels) / (14 + Vwheels) * ((SandDose? sandfactor : 1) - (1 - adh_factor)*(deltaV / (deltaV + slipfactor)));
Vwheels = std::abs( Vwheels );
adhesion = staticfriction * (28 + Vwheels) / (14 + Vwheels) * ((SandDose? sandfactor : 1) - (1 - adh_factor)*(deltaV / (deltaV + slipfactor)));
*/
return adhesion;
}
@@ -4052,24 +4061,11 @@ double TMoverParameters::CouplerForce(int CouplerN, double dt)
// blablabla
// ABu: proby znalezienia problemu ze zle odbijajacymi sie skladami
//if (Couplers[CouplerN].CouplingFlag=ctrain_virtual) and (newdist>0) then
if ((Couplers[CouplerN].CouplingFlag == ctrain_virtual) && (Couplers[CouplerN].CoupleDist > 0))
{
CF = 0; // kontrola zderzania sie - OK
ScanCounter++;
if ((newdist > MaxDist) || ((ScanCounter > MaxCount) && (newdist > MinDist)))
//if (tempdist>MaxDist) or ((ScanCounter>MaxCount)and(tempdist>MinDist)) then
{ // zerwij kontrolnie wirtualny sprzeg
// Connected.Couplers[CNext].Connected:=nil; //Ra: ten podłączony niekoniecznie jest
// wirtualny
// Couplers[CouplerN].Connected = NULL;
ScanCounter = static_cast<int>(Random(500.0)); // Q: TODO: cy dobrze przetlumaczone?
// WriteLog(FloatToStr(ScanCounter));
}
}
else
{
if (Couplers[CouplerN].CouplingFlag == ctrain_virtual)
{
if( ( Couplers[ CouplerN ].CouplingFlag != coupling::faux )
|| ( Couplers[ CouplerN ].CoupleDist < 0 ) ) {
if( Couplers[ CouplerN ].CouplingFlag == coupling::faux ) {
BetaAvg = Couplers[CouplerN].beta;
Fmax = (Couplers[CouplerN].FmaxC + Couplers[CouplerN].FmaxB) * CouplerTune;
}
@@ -4145,18 +4141,20 @@ double TMoverParameters::CouplerForce(int CouplerN, double dt)
//***if -tempdist>(DmaxB+Connected^.Couplers[CNext].DmaxB)/10 then {zderzenie}
{
Couplers[CouplerN].CheckCollision = true;
if ((Couplers[CouplerN].CouplerType == Automatic) &&
(Couplers[CouplerN].CouplingFlag ==
0)) // sprzeganie wagonow z samoczynnymi sprzegami}
if( ( Couplers[ CouplerN ].CouplerType == Automatic )
&& ( Couplers[ CouplerN ].CouplingFlag == coupling::faux ) ) {
// sprzeganie wagonow z samoczynnymi sprzegami}
// CouplingFlag:=ctrain_coupler+ctrain_pneumatic+ctrain_controll+ctrain_passenger+ctrain_scndpneumatic;
Couplers[CouplerN].CouplingFlag =
ctrain_coupler | ctrain_pneumatic | ctrain_controll; // EN57
// EN57
Couplers[ CouplerN ].CouplingFlag = coupling::coupler | coupling::brakehose | coupling::mainhose | coupling::control;
}
}
}
}
if (Couplers[CouplerN].CouplingFlag != ctrain_virtual)
if( Couplers[ CouplerN ].CouplingFlag != coupling::faux ) {
// uzgadnianie prawa Newtona
Couplers[CouplerN].Connected->Couplers[1 - CouplerN].CForce = -CF;
Couplers[ CouplerN ].Connected->Couplers[ 1 - CouplerN ].CForce = -CF;
}
return CF;
}

View File

@@ -66,9 +66,9 @@ void ResetTimers()
};
LONGLONG fr, count, oldCount;
// LARGE_INTEGER fr,count;
void UpdateTimers(bool pause)
{
void UpdateTimers(bool pause) {
QueryPerformanceFrequency((LARGE_INTEGER *)&fr);
QueryPerformanceCounter((LARGE_INTEGER *)&count);
DeltaRenderTime = double(count - oldCount) / double(fr);
@@ -78,18 +78,14 @@ void UpdateTimers(bool pause)
fSoundTimer += DeltaTime;
if (fSoundTimer > 0.1)
fSoundTimer = 0.0;
/*
double CurrentTime= double(count)/double(fr);//GetTickCount();
DeltaTime= (CurrentTime-OldTime);
OldTime= CurrentTime;
*/
if (DeltaTime > 1.0)
DeltaTime = 1.0;
}
else
DeltaTime = 0.0; // wszystko stoi, bo czas nie płynie
oldCount = count;
oldCount = count;
// Keep track of the time lapse and frame count
#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
double fTime = ::GetTickCount64() * 0.001f; // Get current time in seconds
@@ -106,6 +102,7 @@ void UpdateTimers(bool pause)
}
fSimulationTime += DeltaTime;
};
};
}; // namespace timer
//---------------------------------------------------------------------------

View File

@@ -2340,7 +2340,7 @@ void TTrack::ConnectionsLog()
}
};
TTrack * TTrack::Neightbour(int s, double &d)
TTrack * TTrack::Connected(int s, double &d) const
{ // zwraca wskaźnik na sąsiedni tor, w kierunku określonym znakiem (s), odwraca (d) w razie
// niezgodności kierunku torów
TTrack *t; // nie zmieniamy kierunku (d), jeśli nie ma toru dalej

View File

@@ -205,7 +205,7 @@ public:
return trNext; };
inline TTrack *CurrentPrev() const {
return trPrev; };
TTrack * Neightbour(int s, double &d);
TTrack *Connected(int s, double &d) const;
bool SetConnections(int i);
bool Switch(int i, double t = -1.0, double d = -1.0);
bool SwitchForced(int i, TDynamicObject *o);

View File

@@ -1430,10 +1430,14 @@ void TTrain::OnCommand_pantographcompressorvalvetoggle( TTrain *Train, command_d
if( Train->mvControlled->bPantKurek3 == false ) {
// connect pantographs with primary tank
Train->mvControlled->bPantKurek3 = true;
// visual feedback:
Train->ggPantCompressorValve.UpdateValue( 0.0 );
}
else {
// connect pantograps with pantograph compressor
Train->mvControlled->bPantKurek3 = false;
// visual feedback:
Train->ggPantCompressorValve.UpdateValue( 1.0 );
}
}
}
@@ -1456,10 +1460,14 @@ void TTrain::OnCommand_pantographcompressoractivate( TTrain *Train, command_data
if( Command.action != GLFW_RELEASE ) {
// press or hold to activate
Train->mvControlled->PantCompFlag = true;
// visual feedback:
Train->ggPantCompressorButton.UpdateValue( 1.0 );
}
else {
// release to disable
Train->mvControlled->PantCompFlag = false;
// visual feedback:
Train->ggPantCompressorButton.UpdateValue( 0.0 );
}
}
@@ -4627,35 +4635,38 @@ bool TTrain::Update( double const Deltatime )
ggBrakeCtrl.UpdateValue(mvOccupied->fBrakeCtrlPos);
ggBrakeCtrl.Update();
}
if (ggLocalBrake.SubModel)
{
if (DynamicObject->Mechanik ?
(DynamicObject->Mechanik->AIControllFlag ? false : (Global::iFeedbackMode == 4 || (Global::bMWDmasterEnable && Global::bMWDBreakEnable))) :
false) // nie blokujemy AI
{ // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba
// Firleju: dlatego kasujemy i zastepujemy funkcją w Console
if ((mvOccupied->BrakeLocHandle == FD1))
{
double b = Console::AnalogCalibrateGet(1);
b *= 10.0;
b = clamp<double>( b, 0.0, LocalBrakePosNo); // przycięcie zmiennej do granic
ggLocalBrake.UpdateValue(b); // przesów bez zaokrąglenia
if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("FD1 break position = " + to_string(b));
mvOccupied->LocalBrakePos =
int(1.09 * b); // sposób zaokrąglania jest do ustalenia
if( ggLocalBrake.SubModel ) {
if( ( DynamicObject->Mechanik != nullptr )
&& ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI
&& ( mvOccupied->BrakeLocHandle == FD1 )
&& ( ( Global::iFeedbackMode == 4 )
|| ( Global::bMWDmasterEnable && Global::bMWDBreakEnable ) ) ) {
// Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba
// Firleju: dlatego kasujemy i zastepujemy funkcją w Console
auto const b = clamp<double>(
Console::AnalogCalibrateGet( 1 ) * 10.0,
0.0,
ManualBrakePosNo );
ggLocalBrake.UpdateValue( b ); // przesów bez zaokrąglenia
mvOccupied->LocalBrakePos = int( 1.09 * b ); // sposób zaokrąglania jest do ustalenia
if( ( true == Global::bMWDdebugEnable )
&& ( ( Global::iMWDDebugMode & 4 ) != 0 ) ) {
WriteLog( "FD1 break position = " + to_string( b ) );
}
else // standardowa prodedura z kranem powiązanym z klawiaturą
ggLocalBrake.UpdateValue(double(mvOccupied->LocalBrakePos));
}
else // standardowa prodedura z kranem powiązanym z klawiaturą
ggLocalBrake.UpdateValue(double(mvOccupied->LocalBrakePos));
else {
// standardowa prodedura z kranem powiązanym z klawiaturą
ggLocalBrake.UpdateValue( double( mvOccupied->LocalBrakePos ) );
}
ggLocalBrake.Update();
}
if (ggManualBrake.SubModel != NULL)
{
if (ggManualBrake.SubModel != nullptr) {
ggManualBrake.UpdateValue(double(mvOccupied->ManualBrakePos));
ggManualBrake.Update();
}
ggAlarmChain.Update();
ggBrakeProfileCtrl.Update();
ggBrakeProfileG.Update();
ggBrakeProfileR.Update();
@@ -5629,6 +5640,8 @@ bool TTrain::Update( double const Deltatime )
ggPantRearButtonOff.Update();
ggPantSelectedDownButton.Update();
ggPantAllDownButton.Update();
ggPantCompressorButton.Update();
ggPantCompressorValve.Update();
ggUpperLightButton.Update();
ggLeftLightButton.Update();
@@ -6503,6 +6516,8 @@ void TTrain::clear_cab_controls()
ggPantRearButtonOff.Clear();
ggPantSelectedDownButton.Clear();
ggPantAllDownButton.Clear();
ggPantCompressorButton.Clear();
ggPantCompressorValve.Clear();
ggZbS.Clear();
ggI1B.Clear();
ggI2B.Clear();
@@ -6649,6 +6664,15 @@ void TTrain::set_cab_controls() {
0.0 :
1.0 ) );
}
// auxiliary compressor
ggPantCompressorValve.PutValue(
mvControlled->bPantKurek3 ?
0.0 : // default setting is pantographs connected with primary tank
1.0 );
ggPantCompressorButton.PutValue(
mvControlled->PantCompFlag ?
1.0 :
0.0 );
// converter
if( mvOccupied->ConvSwitchType != "impulse" ) {
ggConverterButton.PutValue(
@@ -7067,6 +7091,8 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
{ "pantalloff_sw:", ggPantAllDownButton },
{ "pantselected_sw:", ggPantSelectedButton },
{ "pantselectedoff_sw:", ggPantSelectedDownButton },
{ "pantcompressor_sw:", ggPantCompressorButton },
{ "pantcompressorvalve_sw:", ggPantCompressorValve },
{ "trainheating_sw:", ggTrainHeatingButton },
{ "signalling_sw:", ggSignallingButton },
{ "door_signalling_sw:", ggDoorSignallingButton },

View File

@@ -299,6 +299,8 @@ public: // reszta może by?publiczna
TGauge ggPantAllDownButton;
TGauge ggPantSelectedButton;
TGauge ggPantSelectedDownButton;
TGauge ggPantCompressorButton;
TGauge ggPantCompressorValve;
// Winger 020304 - wlacznik ogrzewania
TGauge ggTrainHeatingButton;
TGauge ggSignallingButton;

View File

@@ -206,10 +206,10 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
dir = fDirection;
if (pCurrentTrack->eType == tt_Cross)
{
if (!SetCurrentTrack(pCurrentTrack->Neightbour(iSegment, fDirection), 0))
if (!SetCurrentTrack(pCurrentTrack->Connected(iSegment, fDirection), 0))
return false; // wyjście z błędem
}
else if (!SetCurrentTrack(pCurrentTrack->Neightbour(-1, fDirection),
else if (!SetCurrentTrack(pCurrentTrack->Connected(-1, fDirection),
0)) // ustawia fDirection
return false; // wyjście z błędem
if (dir == fDirection) //(pCurrentTrack->iPrevDirection)
@@ -243,10 +243,10 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
dir = fDirection;
if (pCurrentTrack->eType == tt_Cross)
{
if (!SetCurrentTrack(pCurrentTrack->Neightbour(iSegment, fDirection), 1))
if (!SetCurrentTrack(pCurrentTrack->Connected(iSegment, fDirection), 1))
return false; // wyjście z błędem
}
else if (!SetCurrentTrack(pCurrentTrack->Neightbour(1, fDirection),
else if (!SetCurrentTrack(pCurrentTrack->Connected(1, fDirection),
1)) // ustawia fDirection
return false; // wyjście z błędem
if (dir != fDirection) //(pCurrentTrack->iNextDirection)

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 17
#define VERSION_MINOR 905
#define VERSION_MINOR 908
#define VERSION_REVISION 0