16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-20 02:09:19 +02:00

Rework of speed control algorithm for DieselEngine - functions for PESA-DMU

This commit is contained in:
Królik Uszasty
2019-10-12 16:54:33 +02:00
parent 679e68dc00
commit 05c6f5d7c3
9 changed files with 520 additions and 56 deletions

View File

@@ -3149,10 +3149,24 @@ bool TController::IncSpeed()
{ // dla 2Ls150 można zmienić tryb pracy, jeśli jest w liniowym i nie daje rady (wymaga zerowania kierunku)
// mvControlling->ShuntMode=(OrderList[OrderPos]&Shunt)||(fMass>224000.0);
}
if ((mvControlling->SpeedCtrl)&&(mvControlling->Mains)) {// cruise control
auto const SpeedCntrlVel{ (
(ActualProximityDist > std::max(50.0, fMaxProximityDist)) ?
VelDesired :
min_speed(VelDesired, VelNext)) };
if (SpeedCntrlVel >= mvControlling->SpeedCtrlUnit.MinVelocity) {
SpeedCntrl(SpeedCntrlVel);
}
else if (SpeedCntrlVel > 0.1) {
SpeedCntrl(0.0);
}
}
if (mvControlling->EIMCtrlType > 0) {
if (true == Ready)
{
DizelPercentage = (mvControlling->Vel > mvControlling->dizel_minVelfullengage ? 100 : 1);
bool max = (mvControlling->Vel > mvControlling->dizel_minVelfullengage)
|| (mvControlling->SpeedCtrl && mvControlling->ScndCtrlPos > 0);
DizelPercentage = (max ? 100 : 1);
}
break;
}
@@ -3167,11 +3181,12 @@ bool TController::IncSpeed()
}
}
if( false == mvControlling->Mains ) {
SpeedCntrl(0.0);
mvControlling->MainSwitch( true );
mvControlling->ConverterSwitch( true );
mvControlling->CompressorSwitch( true );
}
break;
break;
}
return OK;
}
@@ -3222,6 +3237,14 @@ bool TController::DecSpeed(bool force)
if (mvControlling->EIMCtrlType > 0)
{
DizelPercentage = 0;
if (force) {
SpeedCntrl(0.0); //wylacz od razu tempomat
mvControlling->DecScndCtrl(2);
}
if ((VelDesired > 0.1) && (mvControlling->SpeedCtrlUnit.MinVelocity > VelDesired)) {
SpeedCntrl(0.0); //wylacz od razu tempomat
mvControlling->DecScndCtrl(2);
}
break;
}
@@ -3236,8 +3259,11 @@ bool TController::DecSpeed(bool force)
OK = mvControlling->DecMainCtrl( 1 );
}
}
if (force) // przy aktywacji kabiny jest potrzeba natychmiastowego wyzerowania
OK = mvControlling->DecMainCtrl((mvControlling->MainCtrlPowerPos() > 2 ? 2 : 1));
if (force) { // przy aktywacji kabiny jest potrzeba natychmiastowego wyzerowania
OK = mvControlling->DecMainCtrl((mvControlling->MainCtrlPowerPos() > 2 ? 2 : 1));
SpeedCntrl(0.0); //wylacz od razu tempomat
mvControlling->DecScndCtrl( 2 );
}
break;
}
return OK;
@@ -3469,6 +3495,22 @@ void TController::SpeedSet()
void TController::SpeedCntrl(double DesiredSpeed)
{
while (mvControlling->SpeedCtrlUnit.DesiredPower < mvControlling->SpeedCtrlUnit.MaxPower)
{
mvControlling->SpeedCtrlPowerInc();
}
if (mvControlling->EngineType == TEngineType::DieselEngine)
{
if (DesiredSpeed < 0.1) {
mvControlling->DecScndCtrl(2);
DesiredSpeed = 0;
}
else if (mvControlling->ScndCtrlPos < 1) {
mvControlling->IncScndCtrl(1);
}
mvControlling->RunCommand("SpeedCntrl", DesiredSpeed, mvControlling->CabNo);
}
else
if (mvControlling->ScndCtrlPosNo == 1)
{
mvControlling->IncScndCtrl(1);
@@ -3553,8 +3595,13 @@ void TController::SetTimeControllers()
{
DizelPercentage_Speed = DizelPercentage; //wstepnie procenty
auto MinVel{ std::min(mvControlling->hydro_TC_LockupSpeed, mvControlling->Vmax / 6) }; //minimal velocity
if (VelDesired > MinVel) //more power for faster ride
auto MinVel{ std::min(mvControlling->hydro_TC_LockupSpeed, mvControlling->Vmax / 6) }; //minimal velocity
//when speed controll unit is active - start with the procedure
if ((mvControlling->SpeedCtrl) && (mvControlling->ScndCtrlPos > 0)) {
if ((mvControlling->ScndCtrlPos > 0) && (mvControlling->Vel < 1 + mvControlling->SpeedCtrlUnit.StartVelocity) && (DizelPercentage > 0))
DizelPercentage_Speed = 101; //keep last position to start
}
else if (VelDesired > MinVel) //more power for faster ride
{
auto const Factor{ 10 * (mvControlling->Vmax) / (mvControlling->Vmax + 3 * mvControlling->Vel) };
auto DesiredPercentage{ clamp(
@@ -3568,7 +3615,7 @@ void TController::SetTimeControllers()
}
DizelPercentage_Speed = std::round(DesiredPercentage * DizelPercentage);
}
else
else //slow acceleration during shunting wth minimal velocity
{
DizelPercentage_Speed = std::min(DizelPercentage, mvControlling->Vel < 0.99 * VelDesired ? 1 : 0);
}
@@ -4367,9 +4414,11 @@ TController::UpdateSituation(double dt) {
while (p)
{ // sprawdzenie odhamowania wszystkich połączonych pojazdów
auto *vehicle { p->MoverParameters };
double bp = vehicle->BrakePress - (vehicle->SpeedCtrlUnit.Parking ? vehicle->MaxBrakePress[0] * vehicle->StopBrakeDecc : 0.0);
if (bp < 0) bp = 0;
if (Ready) {
// bo jak coś nie odhamowane, to dalej nie ma co sprawdzać
if (vehicle->BrakePress >= 0.4) // wg UIC określone sztywno na 0.04
if (bp >= 0.4) // wg UIC określone sztywno na 0.04
{
Ready = false; // nie gotowy
// Ra: odluźnianie przeładowanych lokomotyw, ciągniętych na zimno - prowizorka...
@@ -4385,8 +4434,8 @@ TController::UpdateSituation(double dt) {
}
}
}
if (fReady < vehicle->BrakePress)
fReady = vehicle->BrakePress; // szukanie najbardziej zahamowanego
if (fReady < bp)
fReady = bp; // szukanie najbardziej zahamowanego
if( ( dy = p->VectorFront().y ) != 0.0 ) {
// istotne tylko dla pojazdów na pochyleniu
// ciężar razy składowa styczna grawitacji

View File

@@ -2763,8 +2763,10 @@ bool TDynamicObject::Update(double dt, double dt1)
&& (MoverParameters->EngineType == TEngineType::DieselEngine)
&& (MoverParameters->EIMCtrlType > 0)) {
MoverParameters->CheckEIMIC(dt1);
MoverParameters->eimic_real = MoverParameters->eimic;
MoverParameters->SendCtrlToNext("EIMIC", MoverParameters->eimic, MoverParameters->CabNo);
if (MoverParameters->SpeedCtrl)
MoverParameters->CheckSpeedCtrl(dt1);
MoverParameters->eimic_real = std::min(MoverParameters->eimic,MoverParameters->eimicSpeedCtrl);
MoverParameters->SendCtrlToNext("EIMIC", MoverParameters->eimic_real, MoverParameters->CabNo);
}
if( ( Mechanik->Primary() )
&& ( MoverParameters->EngineType == TEngineType::ElectricInductionMotor ) ) {
@@ -2784,10 +2786,10 @@ bool TDynamicObject::Update(double dt, double dt1)
if (MoverParameters->Power < 1)
{
MoverParameters->MainCtrlPos = ctOwner->Controlling()->MainCtrlPos*MoverParameters->MainCtrlPosNo / std::max(1, ctOwner->Controlling()->MainCtrlPosNo);
MoverParameters->ScndCtrlActualPos = ctOwner->Controlling()->ScndCtrlActualPos;
MoverParameters->SpeedCtrlValue = ctOwner->Controlling()->SpeedCtrlValue;
}
MoverParameters->CheckEIMIC(dt1);
MoverParameters->CheckSpeedCtrl();
MoverParameters->CheckSpeedCtrl(dt1);
auto eimic = Min0R(MoverParameters->eimic, MoverParameters->eimicSpeedCtrl);
MoverParameters->eimic_real = eimic;

View File

@@ -679,7 +679,32 @@ struct neighbour_data {
float distance { 10000.f }; // distance to the obstacle // NOTE: legacy value. TBD, TODO: use standard -1 instead?
};
struct speed_control {
bool IsActive = false;
bool Start = false;
bool ManualStateOverride = true;
bool BrakeIntervention = false;
bool BrakeInterventionBraking = false;
bool BrakeInterventionUnbraking = false;
bool Standby = true;
bool Parking = false;
double InitialPower = 0.3;
double FullPowerVelocity = 3;
double StartVelocity = 3;
double VelocityStep = 5;
double PowerStep = 0.1;
double MinPower = 0.3;
double MaxPower = 1.0;
double MinVelocity = 20;
double MaxVelocity = 120;
double DesiredVelocity = 0;
double DesiredPower = 1.0;
double Offset = -0.5;
double FactorPpos = 0.1;
double FactorPneg = 0.4;
double FactorIpos = 0.04;
double FactorIneg = 0.0;
};
class TMoverParameters
{ // Ra: wrapper na kod pascalowy, przejmujący jego funkcje Q: 20160824 - juz nie wrapper a klasa bazowa :)
@@ -1185,7 +1210,11 @@ public:
#endif
double MirrorMaxShift { 90.0 };
bool ScndS = false; /*Czy jest bocznikowanie na szeregowej*/
bool SpeedCtrl = false; /*czy jest tempomat*/
speed_control SpeedCtrlUnit; /*parametry tempomatu*/
double SpeedCtrlButtons[10] { 30, 40, 50, 60, 70, 80, 90, 100, 110, 120 }; /*przyciski prędkości*/
double SpeedCtrlDelay = 2; /*opoznienie dzialania tempomatu z wybieralna predkoscia*/
double SpeedCtrlValue = 0; /*wybrana predkosc jazdy na tempomacie*/
/*--sekcja zmiennych*/
/*--opis konkretnego egzemplarza taboru*/
TLocation Loc { 0.0, 0.0, 0.0 }; //pozycja pojazdów do wyznaczenia odległości pomiędzy sprzęgami
@@ -1398,6 +1427,7 @@ public:
static std::vector<std::string> const eimv_labels;
double SpeedCtrlTimer = 0; /*zegar dzialania tempomatu z wybieralna predkoscia*/
double eimicSpeedCtrl = 0; /*pozycja sugerowana przez tempomat*/
double eimicSpeedCtrlIntegral = 0; /*calkowany blad ustawienia predkosci*/
double NewSpeed = 0; /*nowa predkosc do zadania*/
double MED_EPVC_CurrentTime = 0; /*aktualny czas licznika czasu korekcji siły EP*/
@@ -1625,7 +1655,12 @@ public:
bool PantRear( bool const State, range_t const Notify = range_t::consist ); //obsluga pantografu tylnego
void CheckEIMIC(double dt); //sprawdzenie i zmiana nastawy zintegrowanego nastawnika jazdy/hamowania
void CheckSpeedCtrl();
void CheckSpeedCtrl(double dt);
void SpeedCtrlButton(int button);
void SpeedCtrlInc();
void SpeedCtrlDec();
void SpeedCtrlPowerInc();
void SpeedCtrlPowerDec();
/*-funkcje typowe dla lokomotywy spalinowej z przekladnia mechaniczna*/
bool dizel_EngageSwitch(double state);
@@ -1675,6 +1710,7 @@ private:
void LoadFIZ_Security( std::string const &line );
void LoadFIZ_Clima( std::string const &line );
void LoadFIZ_Power( std::string const &Line );
void LoadFIZ_SpeedControl( std::string const &Line );
void LoadFIZ_Engine( std::string const &Input );
void LoadFIZ_Switches( std::string const &Input );
void LoadFIZ_MotorParamTable( std::string const &Input );

View File

@@ -1789,7 +1789,10 @@ bool TMoverParameters::IncMainCtrl(int CtrlSpeed)
++MainCtrlPos;
OK = true;
if ((EIMCtrlType == 0) && (SpeedCtrlAutoTurnOffFlag == 1) && (MainCtrlActualPos != MainCtrlPos))
{
DecScndCtrl(2);
SpeedCtrlUnit.IsActive = false;
}
}
break;
}
@@ -1952,8 +1955,10 @@ bool TMoverParameters::DecMainCtrl(int CtrlSpeed)
{
MainCtrlPos--;
OK = true;
if ((EIMCtrlType == 0) && (SpeedCtrlAutoTurnOffFlag == 1) && (MainCtrlActualPos != MainCtrlPos))
if ((EIMCtrlType == 0) && (SpeedCtrlAutoTurnOffFlag == 1) && (MainCtrlActualPos != MainCtrlPos)) {
DecScndCtrl(2);
SpeedCtrlUnit.IsActive = false;
}
}
else if (CtrlSpeed > 1)
OK = (DecMainCtrl(1) && DecMainCtrl(2)); // CtrlSpeed-1);
@@ -2099,14 +2104,22 @@ bool TMoverParameters::IncScndCtrl(int CtrlSpeed)
{
// NOTE: round() already adds 0.5, are the ones added here as well correct?
if ((Vmax < 250))
ScndCtrlActualPos = Round(Vel);
SpeedCtrlValue = Round(Vel);
else
ScndCtrlActualPos = Round(Vel * 0.5);
SpeedCtrlValue = Round(Vel * 0.5);
if ((EIMCtrlType == 0)&&(SpeedCtrlAutoTurnOffFlag == 1))
{
MainCtrlActualPos = MainCtrlPos;
}
SendCtrlToNext("SpeedCntrl", ScndCtrlActualPos, CabNo);
SpeedCtrlUnit.IsActive = true;
SendCtrlToNext("SpeedCntrl", SpeedCtrlValue, CabNo);
}
if ((OK) && (SpeedCtrl) && (ScndCtrlPos == 1) && (EngineType == TEngineType::DieselEngine))
{
// NOTE: round() already adds 0.5, are the ones added here as well correct?
SpeedCtrlValue = Round(Vel);
SpeedCtrlUnit.IsActive = true;
}
return OK;
@@ -2159,8 +2172,16 @@ bool TMoverParameters::DecScndCtrl(int CtrlSpeed)
if ((OK) && (EngineType == TEngineType::ElectricInductionMotor) && (ScndCtrlPosNo == 1))
{
ScndCtrlActualPos = 0;
SendCtrlToNext("SpeedCntrl", ScndCtrlActualPos, CabNo);
SpeedCtrlValue = 0;
SendCtrlToNext("SpeedCntrl", SpeedCtrlValue, CabNo);
SpeedCtrlUnit.IsActive = false;
}
if ((OK) && (SpeedCtrl) && (ScndCtrlPos == 0) && (EngineType == TEngineType::DieselEngine))
{
// NOTE: round() already adds 0.5, are the ones added here as well correct?
SpeedCtrlValue = 0;
SpeedCtrlUnit.IsActive = false;
}
return OK;
@@ -3811,8 +3832,13 @@ void TMoverParameters::UpdatePipePressure(double dt)
if( BrakeCtrlPosNo > 1 ) {
if ((EngineType != TEngineType::ElectricInductionMotor))
dpLocalValve = LocHandle->GetPF(std::max(LocalBrakePosA, LocalBrakePosAEIM), Hamulec->GetBCP(), ScndPipePress, dt, 0);
if ((EngineType != TEngineType::ElectricInductionMotor)) {
double lbpa = LocalBrakePosA;
if (SpeedCtrlUnit.Parking) {
lbpa = std::max(lbpa, StopBrakeDecc);
}
dpLocalValve = LocHandle->GetPF(std::max(lbpa, LocalBrakePosAEIM), Hamulec->GetBCP(), ScndPipePress, dt, 0);
}
else
dpLocalValve = LocHandle->GetPF(LocalBrakePosAEIM, Hamulec->GetBCP(), ScndPipePress, dt, 0);
@@ -3841,7 +3867,15 @@ void TMoverParameters::UpdatePipePressure(double dt)
|| ( ( Handle->GetPos( bh_EB ) - 0.5 ) < BrakeCtrlPosR )
|| ( ( BrakeHandle != TBrakeHandle::MHZ_EN57 )
&& ( BrakeHandle != TBrakeHandle::MHZ_K8P ) ) ) {
dpMainValve = Handle->GetPF( BrakeCtrlPosR, PipePress, temp, dt, EqvtPipePress );
double pos = BrakeCtrlPosR;
if (SpeedCtrl && SpeedCtrlUnit.BrakeIntervention && !SpeedCtrlUnit.Standby) {
pos = Handle->GetPos(bh_NP);
if (SpeedCtrlUnit.BrakeInterventionBraking)
pos = Handle->GetPos(bh_FB);
if (SpeedCtrlUnit.BrakeInterventionUnbraking)
pos = Handle->GetPos(bh_RP);
}
dpMainValve = Handle->GetPF( pos, PipePress, temp, dt, EqvtPipePress );
}
else {
dpMainValve = Handle->GetPF( 0, PipePress, temp, dt, EqvtPipePress );
@@ -5383,7 +5417,7 @@ double TMoverParameters::TractionForce( double dt ) {
switch (ScndCtrlPos) {
case 0:
NewSpeed = 0;
ScndCtrlActualPos = 0;
SpeedCtrlValue = 0;
SpeedCtrlTimer = 10;
break;
case 1:
@@ -5397,7 +5431,7 @@ double TMoverParameters::TractionForce( double dt ) {
break;
case 2:
SpeedCtrlTimer = 10;
ScndCtrlActualPos = NewSpeed;
SpeedCtrlValue = NewSpeed;
break;
case 3:
if (SpeedCtrlTimer > SpeedCtrlDelay) {
@@ -5410,7 +5444,7 @@ double TMoverParameters::TractionForce( double dt ) {
break;
case 4:
NewSpeed = Vmax;
ScndCtrlActualPos = Vmax;
SpeedCtrlValue = Vmax;
SpeedCtrlTimer = 10;
break;
}
@@ -5429,10 +5463,10 @@ double TMoverParameters::TractionForce( double dt ) {
if (SpeedCtrlTimer > SpeedCtrlDelay)
{
int NewSCAP = (Vmax < 250 ? 1 : 0.5) * (float)ScndCtrlPos / (float)ScndCtrlPosNo * Vmax;
if (NewSCAP != ScndCtrlActualPos)
if (NewSCAP != SpeedCtrlValue)
{
ScndCtrlActualPos = NewSCAP;
// SendCtrlToNext("SpeedCntrl", ScndCtrlActualPos, CabNo);
SpeedCtrlValue = NewSCAP;
// SendCtrlToNext("SpeedCntrl", SpeedCtrlValue, CabNo);
}
}
}
@@ -5489,12 +5523,12 @@ double TMoverParameters::TractionForce( double dt ) {
eimv[eimv_Fzad] = PosRatio;
if ((Flat) && (eimc[eimc_p_F0] * eimv[eimv_Fful] > 0))
PosRatio = Min0R(PosRatio * eimc[eimc_p_F0] / eimv[eimv_Fful], 1);
/* if (ScndCtrlActualPos > 0) //speed control
/* if (SpeedCtrlValue > 0) //speed control
if (Vmax < 250)
PosRatio = Min0R(PosRatio, Max0R(-1, 0.5 * (ScndCtrlActualPos - Vel)));
PosRatio = Min0R(PosRatio, Max0R(-1, 0.5 * (SpeedCtrlValue - Vel)));
else
PosRatio =
Min0R(PosRatio, Max0R(-1, 0.5 * (ScndCtrlActualPos * 2 - Vel))); */
Min0R(PosRatio, Max0R(-1, 0.5 * (SpeedCtrlValue * 2 - Vel))); */
// PosRatio = 1.0 * (PosRatio * 0 + 1) * PosRatio; // 1 * 1 * PosRatio = PosRatio
Hamulec->SetED(0);
// (Hamulec as TLSt).SetLBP(LocBrakePress);
@@ -6475,15 +6509,106 @@ void TMoverParameters::CheckEIMIC(double dt)
eimic = clamp(eimic, -1.0, eimicpowerenabled ? 1.0 : 0.0);
}
void TMoverParameters::CheckSpeedCtrl()
void TMoverParameters::CheckSpeedCtrl(double dt)
{
if (ScndCtrlActualPos > 0) //speed control
if (Vmax < 250)
eimicSpeedCtrl = clamp(0.5 * (ScndCtrlActualPos - Vel), -1.0, 1.0);
else
eimicSpeedCtrl = clamp(0.5 * (ScndCtrlActualPos * 2 - Vel), -1.0, 1.0);
else
if (MainCtrlPos < MainCtrlPosNo - 2) {
SpeedCtrlUnit.Standby = true;
}
if (MainCtrlPos > MainCtrlPosNo - 1) {
SpeedCtrlUnit.Standby = false;
}
if (SpeedCtrlUnit.IsActive) {//speed control
if (EngineType == TEngineType::DieselEngine) {
if ((!SpeedCtrlUnit.Standby)) {
if (SpeedCtrlUnit.ManualStateOverride) {
if (MainCtrlPos < MainCtrlPosNo - 1) {
eimic = std::min(eimic, 0.0);
eimicSpeedCtrlIntegral = 0.0;
}
else if (eimic > 0.009) eimic = 1.0;
}
double error = (std::max(SpeedCtrlValue + SpeedCtrlUnit.Offset, 0.0) - Vel);
double factorP = error > 0 ? SpeedCtrlUnit.FactorPpos : SpeedCtrlUnit.FactorPneg;
double eSCP = clamp(factorP * error, -1.2, 1.0); //P module
if (eSCP < -1.0)
{
SpeedCtrlUnit.BrakeInterventionBraking = (eSCP < -1.1) && (Vel < hydro_TC_UnlockSpeed);
eSCP = -1.0;
}
SpeedCtrlUnit.BrakeInterventionUnbraking = (eSCP > 0.0) || (Vel == 0.0);
if (abs(eSCP) < 0.999) {
//TODO: check how to disable integral part when braking in smart way
//double factorI = eimicSpeedCtrlIntegral >= 0 ? SpeedCtrlUnit.FactorIpos : SpeedCtrlUnit.FactorIneg;
double factorI = eimicSpeedCtrlIntegral >= 0 ? SpeedCtrlUnit.FactorIpos : SpeedCtrlUnit.FactorIneg;
eimicSpeedCtrlIntegral = clamp(eimicSpeedCtrlIntegral + factorI * eSCP * dt, -1.0 + eSCP, 1.0 - eSCP);
}
else {
eimicSpeedCtrlIntegral = 0;
}
eimicSpeedCtrl = clamp(eimicSpeedCtrlIntegral + eSCP, -SpeedCtrlUnit.DesiredPower, SpeedCtrlUnit.DesiredPower);
if (Vel < SpeedCtrlUnit.FullPowerVelocity) {
eimicSpeedCtrl = std::min(eimicSpeedCtrl, SpeedCtrlUnit.InitialPower);
}
if ((Vel < SpeedCtrlUnit.StartVelocity) && (MainCtrlPos < MainCtrlPosNo)) {
eimicSpeedCtrl = 0;
eimic = 0;
}
}
else {
eimicSpeedCtrl = 1;
eimicSpeedCtrlIntegral = 0;
}
SpeedCtrlUnit.Parking = (Vel == 0.0) & (eimic <= 0);
SendCtrlToNext("SpeedCtrlUnit.Parking", SpeedCtrlUnit.Parking, CabNo);
}
else {
if (Vmax < 250)
eimicSpeedCtrl = clamp(0.5 * (SpeedCtrlValue - Vel), -1.0, 1.0);
else
eimicSpeedCtrl = clamp(0.5 * (SpeedCtrlValue * 2 - Vel), -1.0, 1.0);
}
}
else {
eimicSpeedCtrl = 1;
eimicSpeedCtrlIntegral = 0;
SpeedCtrlUnit.Parking = false;
}
}
void TMoverParameters::SpeedCtrlButton(int button)
{
if ((SpeedCtrl) && (ScndCtrlPos > 0)) {
SpeedCtrlValue = SpeedCtrlButtons[button];
}
}
void TMoverParameters::SpeedCtrlInc()
{
if ((SpeedCtrl) && (ScndCtrlPos > 0)) {
SpeedCtrlValue = std::min(SpeedCtrlValue + SpeedCtrlUnit.VelocityStep, SpeedCtrlUnit.MaxVelocity);
}
}
void TMoverParameters::SpeedCtrlDec()
{
if ((SpeedCtrl) && (ScndCtrlPos > 0)) {
SpeedCtrlValue = std::max(SpeedCtrlValue - SpeedCtrlUnit.VelocityStep, SpeedCtrlUnit.MinVelocity);
}
}
void TMoverParameters::SpeedCtrlPowerInc()
{
if ((SpeedCtrl) && (ScndCtrlPos > 0)) {
SpeedCtrlUnit.DesiredPower = std::min(SpeedCtrlUnit.DesiredPower + SpeedCtrlUnit.PowerStep, SpeedCtrlUnit.MaxPower);
}
}
void TMoverParameters::SpeedCtrlPowerDec()
{
if ((SpeedCtrl) && (ScndCtrlPos > 0)) {
SpeedCtrlUnit.DesiredPower = std::max(SpeedCtrlUnit.DesiredPower - SpeedCtrlUnit.PowerStep, SpeedCtrlUnit.MinPower);
}
}
// *************************************************************************************************
@@ -8489,6 +8614,14 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
continue;
}
if (issection("SpeedControl:", inputline))
{
startBPT = false;
fizlines.emplace("SpeedControl", inputline);
LoadFIZ_SpeedControl(inputline);
continue;
}
if( issection( "Engine:", inputline ) )
{
startBPT = false;
@@ -9240,14 +9373,6 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
extract_value( StopBrakeDecc, "SBD", line, "" );
// speed control
extract_value( SpeedCtrlDelay, "SpeedCtrlDelay", line, "" );
SpeedCtrlTypeTime =
(extract_value("SpeedCtrlType", line) == "Time") ?
true :
false;
extract_value(SpeedCtrlAutoTurnOffFlag, "SpeedCtrlATOF", line, "");
// converter
{
std::map<std::string, start_t> starts {
@@ -9426,6 +9551,51 @@ void TMoverParameters::LoadFIZ_Power( std::string const &Line ) {
LoadFIZ_PowerParamsDecode( SystemPowerSource, "", Line );
}
void TMoverParameters::LoadFIZ_SpeedControl(std::string const &Line) {
// speed control
SpeedCtrl = extract_value("SpeedCtrl", Line) == "Yes";
if ((!SpeedCtrl) && (EngineType == TEngineType::ElectricInductionMotor) && (ScndCtrlPosNo > 0)) //backward compatibility
SpeedCtrl = true;
extract_value(SpeedCtrlDelay, "SpeedCtrlDelay", Line, "");
SpeedCtrlTypeTime =
(extract_value("SpeedCtrlType", Line) == "Time") ?
true :
false;
extract_value(SpeedCtrlAutoTurnOffFlag, "SpeedCtrlATOF", Line, "");
auto speedpresets = Split(extract_value("SpeedButtons", Line), '|');
int speed_no = 0;
for (auto const &speed : speedpresets) {
SpeedCtrlButtons[speed_no++] = std::stod(speed);
if (speed_no > 9) break;
}
SpeedCtrlUnit.ManualStateOverride =
(extract_value("OverrideManual", Line) == "Yes") ?
true :
false;
SpeedCtrlUnit.BrakeIntervention =
(extract_value("BrakeIntervention", Line) == "Yes") ?
true :
false;
extract_value(SpeedCtrlUnit.InitialPower, "InitPwr", Line, "");
extract_value(SpeedCtrlUnit.FullPowerVelocity, "MaxPwrVel", Line, "");
extract_value(SpeedCtrlUnit.StartVelocity, "StartVel", Line, "");
extract_value(SpeedCtrlUnit.VelocityStep, "VelStep", Line, "");
extract_value(SpeedCtrlUnit.PowerStep, "PwrStep", Line, "");
extract_value(SpeedCtrlUnit.MinPower, "MinPwr", Line, "");
extract_value(SpeedCtrlUnit.MaxPower, "MaxPwr", Line, "");
extract_value(SpeedCtrlUnit.MinVelocity, "MinVel", Line, "");
extract_value(SpeedCtrlUnit.MaxVelocity, "MaxVel", Line, "");
extract_value(SpeedCtrlUnit.Offset, "Offset", Line, "");
extract_value(SpeedCtrlUnit.FactorPpos, "kPpos", Line, "");
extract_value(SpeedCtrlUnit.FactorPneg, "kPneg", Line, "");
extract_value(SpeedCtrlUnit.FactorIpos, "kIpos", Line, "");
extract_value(SpeedCtrlUnit.FactorIneg, "kIneg", Line, "");
}
void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
EngineType = LoadFIZ_EngineDecode( extract_value( "EngineType", Input ) );
@@ -10879,8 +11049,13 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
}
else if (Command == "SpeedCntrl")
{
if ((EngineType == TEngineType::ElectricInductionMotor))
ScndCtrlActualPos = static_cast<int>(round(CValue1));
if ((EngineType == TEngineType::ElectricInductionMotor)||(SpeedCtrl))
SpeedCtrlValue = static_cast<int>(round(CValue1));
OK = SendCtrlToNext(Command, CValue1, CValue2, Couplertype);
}
else if (Command == "SpeedCtrlUnit.Parking")
{
SpeedCtrlUnit.Parking = static_cast<bool>(CValue1);
OK = SendCtrlToNext(Command, CValue1, CValue2, Couplertype);
}
else if (Command == "SpringBrakeActivate")

124
Train.cpp
View File

@@ -363,7 +363,21 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
{ user_command::springbrakeshutofftoggle, &TTrain::OnCommand_springbrakeshutofftoggle },
{ user_command::springbrakeshutoffenable, &TTrain::OnCommand_springbrakeshutoffenable },
{ user_command::springbrakeshutoffdisable, &TTrain::OnCommand_springbrakeshutoffdisable },
{ user_command::springbrakerelease, &TTrain::OnCommand_springbrakerelease }
{ user_command::springbrakerelease, &TTrain::OnCommand_springbrakerelease },
{ user_command::speedcontrolincrease, &TTrain::OnCommand_speedcontrolincrease },
{ user_command::speedcontroldecrease, &TTrain::OnCommand_speedcontroldecrease },
{ user_command::speedcontrolpowerincrease, &TTrain::OnCommand_speedcontrolpowerincrease },
{ user_command::speedcontrolpowerdecrease, &TTrain::OnCommand_speedcontrolpowerdecrease },
{ user_command::speedcontrolbutton0, &TTrain::OnCommand_speedcontrolbutton },
{ user_command::speedcontrolbutton1, &TTrain::OnCommand_speedcontrolbutton },
{ user_command::speedcontrolbutton2, &TTrain::OnCommand_speedcontrolbutton },
{ user_command::speedcontrolbutton3, &TTrain::OnCommand_speedcontrolbutton },
{ user_command::speedcontrolbutton4, &TTrain::OnCommand_speedcontrolbutton },
{ user_command::speedcontrolbutton5, &TTrain::OnCommand_speedcontrolbutton },
{ user_command::speedcontrolbutton6, &TTrain::OnCommand_speedcontrolbutton },
{ user_command::speedcontrolbutton7, &TTrain::OnCommand_speedcontrolbutton },
{ user_command::speedcontrolbutton8, &TTrain::OnCommand_speedcontrolbutton },
{ user_command::speedcontrolbutton9, &TTrain::OnCommand_speedcontrolbutton },
};
std::vector<std::string> const TTrain::fPress_labels = {
@@ -475,6 +489,8 @@ dictionary_source *TTrain::GetTrainState() {
dict->insert( "scndctrl_pos", mvControlled->ScndCtrlPos );
dict->insert( "scnd_ctrl_actual_pos", mvControlled->ScndCtrlActualPos );
dict->insert( "new_speed", mover->NewSpeed);
dict->insert( "speedctrl", mover->SpeedCtrlValue);
dict->insert( "speedctrlpower", mover->SpeedCtrlUnit.DesiredPower);
// brakes
dict->insert( "manual_brake", ( mvOccupied->ManualBrakePos > 0 ) );
bool const bEP = ( mvControlled->LocHandle->GetCP() > 0.2 ) || ( fEIMParams[ 0 ][ 2 ] > 0.01 );
@@ -4485,6 +4501,80 @@ void TTrain::OnCommand_springbrakerelease(TTrain *Train, command_data const &Com
}
};
void TTrain::OnCommand_speedcontrolincrease(TTrain *Train, command_data const &Command) {
if (Command.action == GLFW_PRESS) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down
Train->mvOccupied->SpeedCtrlInc();
// visual feedback
Train->ggSpeedControlIncreaseButton.UpdateValue(1.0, Train->dsbSwitch);
}
else if (Command.action == GLFW_RELEASE) {
// release
// visual feedback
Train->ggSpeedControlIncreaseButton.UpdateValue(0.0, Train->dsbSwitch);
}
};
void TTrain::OnCommand_speedcontroldecrease(TTrain *Train, command_data const &Command) {
if (Command.action == GLFW_PRESS) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down
Train->mvOccupied->SpeedCtrlDec();
// visual feedback
Train->ggSpeedControlDecreaseButton.UpdateValue(1.0, Train->dsbSwitch);
}
else if (Command.action == GLFW_RELEASE) {
// release
// visual feedback
Train->ggSpeedControlDecreaseButton.UpdateValue(0.0, Train->dsbSwitch);
}
};
void TTrain::OnCommand_speedcontrolpowerincrease(TTrain *Train, command_data const &Command) {
if (Command.action == GLFW_PRESS) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down
Train->mvOccupied->SpeedCtrlPowerInc();
// visual feedback
Train->ggSpeedControlPowerIncreaseButton.UpdateValue(1.0, Train->dsbSwitch);
}
else if (Command.action == GLFW_RELEASE) {
// release
// visual feedback
Train->ggSpeedControlPowerIncreaseButton.UpdateValue(0.0, Train->dsbSwitch);
}
};
void TTrain::OnCommand_speedcontrolpowerdecrease(TTrain *Train, command_data const &Command) {
if (Command.action == GLFW_PRESS) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down
Train->mvOccupied->SpeedCtrlPowerDec();
// visual feedback
Train->ggSpeedControlPowerDecreaseButton.UpdateValue(1.0, Train->dsbSwitch);
}
else if (Command.action == GLFW_RELEASE) {
// release
// visual feedback
Train->ggSpeedControlPowerDecreaseButton.UpdateValue(0.0, Train->dsbSwitch);
}
};
void TTrain::OnCommand_speedcontrolbutton(TTrain *Train, command_data const &Command) {
auto const itemindex = static_cast<int>(Command.command) - static_cast<int>(user_command::speedcontrolbutton0);
auto &item = Train->ggSpeedCtrlButtons[itemindex];
if (Command.action == GLFW_PRESS) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down
Train->mvOccupied->SpeedCtrlButton(itemindex);
// visual feedback
Train->ggSpeedCtrlButtons[itemindex].UpdateValue(1.0, Train->dsbSwitch);
}
else if (Command.action == GLFW_RELEASE) {
// release
// visual feedback
Train->ggSpeedCtrlButtons[itemindex].UpdateValue(0.0, Train->dsbSwitch);
}
};
void TTrain::OnCommand_doorlocktoggle( TTrain *Train, command_data const &Command ) {
if( Train->ggDoorSignallingButton.SubModel == nullptr ) {
@@ -6460,6 +6550,15 @@ bool TTrain::Update( double const Deltatime )
ggHelperButton.UpdateValue( DynamicObject->Mechanik->HelperState );
}
ggHelperButton.Update();
ggSpeedControlIncreaseButton.Update();
ggSpeedControlDecreaseButton.Update();
ggSpeedControlPowerIncreaseButton.Update();
ggSpeedControlDecreaseButton.Update();
for (auto &speedctrlbutton : ggSpeedCtrlButtons) {
speedctrlbutton.Update();
}
for( auto &universal : ggUniversals ) {
universal.Update();
}
@@ -7616,6 +7715,13 @@ void TTrain::clear_cab_controls()
ggWhistleButton.Clear();
ggHelperButton.Clear();
ggNextCurrentButton.Clear();
ggSpeedControlIncreaseButton.Clear();
ggSpeedControlDecreaseButton.Clear();
ggSpeedControlPowerIncreaseButton.Clear();
ggSpeedControlDecreaseButton.Clear();
for (auto &speedctrlbutton : ggSpeedCtrlButtons) {
speedctrlbutton.Clear();
}
for( auto &universal : ggUniversals ) {
universal.Clear();
}
@@ -8364,7 +8470,21 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
{ "universal6:", ggUniversals[ 6 ] },
{ "universal7:", ggUniversals[ 7 ] },
{ "universal8:", ggUniversals[ 8 ] },
{ "universal9:", ggUniversals[ 9 ] }
{ "universal9:", ggUniversals[ 9 ] },
{ "speedinc_bt:", ggSpeedControlIncreaseButton },
{ "speeddec_bt:", ggSpeedControlDecreaseButton },
{ "speedctrlpowerinc_bt:", ggSpeedControlPowerIncreaseButton },
{ "speedctrlpowerdec_bt:", ggSpeedControlPowerDecreaseButton },
{ "speedbutton0:", ggSpeedCtrlButtons[ 0 ] },
{ "speedbutton1:", ggSpeedCtrlButtons[ 1 ] },
{ "speedbutton2:", ggSpeedCtrlButtons[ 2 ] },
{ "speedbutton3:", ggSpeedCtrlButtons[ 3 ] },
{ "speedbutton4:", ggSpeedCtrlButtons[ 4 ] },
{ "speedbutton5:", ggSpeedCtrlButtons[ 5 ] },
{ "speedbutton6:", ggSpeedCtrlButtons[ 6 ] },
{ "speedbutton7:", ggSpeedCtrlButtons[ 7 ] },
{ "speedbutton8:", ggSpeedCtrlButtons[ 8 ] },
{ "speedbutton9:", ggSpeedCtrlButtons[ 9 ] }
};
{
auto lookup = gauges.find( Label );

13
Train.h
View File

@@ -360,6 +360,12 @@ class TTrain
static void OnCommand_springbrakeshutoffenable(TTrain *Train, command_data const &Command);
static void OnCommand_springbrakeshutoffdisable(TTrain *Train, command_data const &Command);
static void OnCommand_springbrakerelease(TTrain *Train, command_data const &Command);
static void OnCommand_speedcontrolincrease(TTrain *Train, command_data const &Command);
static void OnCommand_speedcontroldecrease(TTrain *Train, command_data const &Command);
static void OnCommand_speedcontrolpowerincrease(TTrain *Train, command_data const &Command);
static void OnCommand_speedcontrolpowerdecrease(TTrain *Train, command_data const &Command);
static void OnCommand_speedcontrolbutton(TTrain *Train, command_data const &Command);
// members
@@ -466,6 +472,13 @@ public: // reszta może by?publiczna
TGauge ggHelperButton;
TGauge ggNextCurrentButton;
// yB 191005 - tempomat
TGauge ggSpeedControlIncreaseButton;
TGauge ggSpeedControlDecreaseButton;
TGauge ggSpeedControlPowerIncreaseButton;
TGauge ggSpeedControlPowerDecreaseButton;
std::array<TGauge, 10> ggSpeedCtrlButtons; // NOTE: temporary arrangement until we have dynamically built control table
std::array<TGauge, 10> ggUniversals; // NOTE: temporary arrangement until we have dynamically built control table
TGauge ggInstrumentLightButton;

View File

@@ -243,7 +243,21 @@ commanddescription_sequence Commands_descriptions = {
{ "springbrakeshutofftoggle", command_target::vehicle },
{ "springbrakeshutoffenable", command_target::vehicle },
{ "springbrakeshutoffdisable", command_target::vehicle },
{ "springbrakerelease", command_target::vehicle }
{ "springbrakerelease", command_target::vehicle },
{ "speedcontrolincrease", command_target::vehicle },
{ "speedcontroldecrease", command_target::vehicle },
{ "speedcontrolpowerincrease", command_target::vehicle },
{ "speedcontrolpowerdecrease", command_target::vehicle },
{ "speedcontrolbutton0", command_target::vehicle },
{ "speedcontrolbutton1", command_target::vehicle },
{ "speedcontrolbutton2", command_target::vehicle },
{ "speedcontrolbutton3", command_target::vehicle },
{ "speedcontrolbutton4", command_target::vehicle },
{ "speedcontrolbutton5", command_target::vehicle },
{ "speedcontrolbutton6", command_target::vehicle },
{ "speedcontrolbutton7", command_target::vehicle },
{ "speedcontrolbutton8", command_target::vehicle },
{ "speedcontrolbutton9", command_target::vehicle }
};

View File

@@ -237,7 +237,20 @@ enum class user_command {
springbrakeshutoffenable,
springbrakeshutoffdisable,
springbrakerelease,
speedcontrolincrease,
speedcontroldecrease,
speedcontrolpowerincrease,
speedcontrolpowerdecrease,
speedcontrolbutton0,
speedcontrolbutton1,
speedcontrolbutton2,
speedcontrolbutton3,
speedcontrolbutton4,
speedcontrolbutton5,
speedcontrolbutton6,
speedcontrolbutton7,
speedcontrolbutton8,
speedcontrolbutton9,
none = -1
};

View File

@@ -818,7 +818,49 @@ drivermouse_input::default_bindings() {
user_command::none } },
{ "universal9:", {
user_command::generictoggle9,
user_command::none } }
user_command::none } },
{ "speedinc_bt:",{
user_command::speedcontrolincrease,
user_command::none } },
{ "speeddec_bt:",{
user_command::speedcontroldecrease,
user_command::none } },
{ "speedctrlpowerinc_bt:",{
user_command::speedcontrolpowerincrease,
user_command::none } },
{ "speedctrlpowerdec_bt:",{
user_command::speedcontrolpowerdecrease,
user_command::none } },
{ "speedbutton0:",{
user_command::speedcontrolbutton0,
user_command::none } },
{ "speedbutton1:",{
user_command::speedcontrolbutton1,
user_command::none } },
{ "speedbutton2:",{
user_command::speedcontrolbutton2,
user_command::none } },
{ "speedbutton3:",{
user_command::speedcontrolbutton3,
user_command::none } },
{ "speedbutton4:",{
user_command::speedcontrolbutton4,
user_command::none } },
{ "speedbutton5:",{
user_command::speedcontrolbutton5,
user_command::none } },
{ "speedbutton6:",{
user_command::speedcontrolbutton6,
user_command::none } },
{ "speedbutton7:",{
user_command::speedcontrolbutton7,
user_command::none } },
{ "speedbutton8:",{
user_command::speedcontrolbutton8,
user_command::none } },
{ "speedbutton9:",{
user_command::speedcontrolbutton9,
user_command::none } }
};
}