[webthrottle] Added option for immediate speed control, bypassing acceleration/deceleration.
Dieser Commit ist enthalten in:
Ursprung
e3ae8f309d
Commit
95808edd4c
@ -87,14 +87,21 @@ Throttle::Throttle(World& world, std::string_view _id)
|
|||||||
return false;
|
return false;
|
||||||
}}
|
}}
|
||||||
, stop{*this, "stop",
|
, stop{*this, "stop",
|
||||||
[this]()
|
[this](bool immediate)
|
||||||
{
|
{
|
||||||
if(acquired())
|
if(acquired())
|
||||||
{
|
{
|
||||||
if(train)
|
if(train)
|
||||||
{
|
{
|
||||||
train->emergencyStop = false;
|
train->emergencyStop = false;
|
||||||
train->stop();
|
if(immediate)
|
||||||
|
{
|
||||||
|
train->setSpeed(*this, 0.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
train->setTargetSpeed(*this, 0.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(m_decoder)
|
if(m_decoder)
|
||||||
{
|
{
|
||||||
@ -106,32 +113,50 @@ Throttle::Throttle(World& world, std::string_view _id)
|
|||||||
return false;
|
return false;
|
||||||
}}
|
}}
|
||||||
, faster{*this, "faster",
|
, faster{*this, "faster",
|
||||||
[this]()
|
[this](bool immediate)
|
||||||
{
|
{
|
||||||
if(acquired())
|
if(acquired())
|
||||||
{
|
{
|
||||||
if(train)
|
if(train)
|
||||||
{
|
{
|
||||||
const double value = train->throttleSpeed.value();
|
|
||||||
const double step = getValueStep(value, train->throttleSpeed.unit());
|
|
||||||
train->emergencyStop = false;
|
train->emergencyStop = false;
|
||||||
train->setTargetSpeed(*this, valueStepUp(value, step));
|
if(immediate)
|
||||||
|
{
|
||||||
|
const double value = train->speed.value();
|
||||||
|
const double step = getValueStep(value, train->speed.unit());
|
||||||
|
train->setSpeed(*this, valueStepUp(value, step));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const double value = train->throttleSpeed.value();
|
||||||
|
const double step = getValueStep(value, train->throttleSpeed.unit());
|
||||||
|
train->setTargetSpeed(*this, valueStepUp(value, step));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}}
|
}}
|
||||||
, slower{*this, "slower",
|
, slower{*this, "slower",
|
||||||
[this]()
|
[this](bool immediate)
|
||||||
{
|
{
|
||||||
if(acquired())
|
if(acquired())
|
||||||
{
|
{
|
||||||
if(train)
|
if(train)
|
||||||
{
|
{
|
||||||
const double value = train->throttleSpeed.value();
|
|
||||||
const double step = getValueStep(value, train->throttleSpeed.unit());
|
|
||||||
train->emergencyStop = false;
|
train->emergencyStop = false;
|
||||||
train->setTargetSpeed(*this, valueStepDown(value, step));
|
if(immediate)
|
||||||
|
{
|
||||||
|
const double value = train->speed.value();
|
||||||
|
const double step = getValueStep(value, train->speed.unit());
|
||||||
|
train->setSpeed(*this, valueStepDown(value, step));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const double value = train->throttleSpeed.value();
|
||||||
|
const double step = getValueStep(value, train->throttleSpeed.unit());
|
||||||
|
train->setTargetSpeed(*this, valueStepDown(value, step));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,9 +72,9 @@ class Throttle : public IdObject
|
|||||||
Property<float> throttle;
|
Property<float> throttle;
|
||||||
ObjectProperty<Train> train;
|
ObjectProperty<Train> train;
|
||||||
Method<bool()> emergencyStop;
|
Method<bool()> emergencyStop;
|
||||||
Method<bool()> stop;
|
Method<bool(bool)> stop;
|
||||||
Method<bool()> faster;
|
Method<bool(bool)> faster;
|
||||||
Method<bool()> slower;
|
Method<bool(bool)> slower;
|
||||||
Method<bool(Direction)> setDirection;
|
Method<bool(Direction)> setDirection;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|||||||
@ -301,15 +301,15 @@ void WebThrottleConnection::processMessage(const nlohmann::json& message)
|
|||||||
}
|
}
|
||||||
else if(action == "stop")
|
else if(action == "stop")
|
||||||
{
|
{
|
||||||
throttle->stop();
|
throttle->stop(message.value("immediate", false));
|
||||||
}
|
}
|
||||||
else if(action == "faster")
|
else if(action == "faster")
|
||||||
{
|
{
|
||||||
throttle->faster();
|
throttle->faster(message.value("immediate", false));
|
||||||
}
|
}
|
||||||
else if(action == "slower")
|
else if(action == "slower")
|
||||||
{
|
{
|
||||||
throttle->slower();
|
throttle->slower(message.value("immediate", false));
|
||||||
}
|
}
|
||||||
else if(action == "reverse" || action == "forward")
|
else if(action == "reverse" || action == "forward")
|
||||||
{
|
{
|
||||||
|
|||||||
@ -501,6 +501,30 @@ std::error_code Train::release(Throttle& throttle)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::error_code Train::setSpeed(Throttle& throttle, double value)
|
||||||
|
{
|
||||||
|
if(m_throttle.get() != &throttle)
|
||||||
|
{
|
||||||
|
return make_error_code(TrainError::InvalidThrottle);
|
||||||
|
}
|
||||||
|
assert(active);
|
||||||
|
|
||||||
|
value = std::clamp(value, Attributes::getMin(speed), Attributes::getMax(speed));
|
||||||
|
|
||||||
|
setSpeed(convertUnit(value, speed.unit(), SpeedUnit::KiloMeterPerHour));
|
||||||
|
throttleSpeed.setValue(convertUnit(value, speed.unit(), throttleSpeed.unit()));
|
||||||
|
m_speedTimer.cancel();
|
||||||
|
m_speedState = SpeedState::Idle;
|
||||||
|
|
||||||
|
const bool currentValue = isStopped;
|
||||||
|
isStopped.setValueInternal(m_speedState == SpeedState::Idle && almostZero(speed.value()) && almostZero(throttleSpeed.value()));
|
||||||
|
if(currentValue != isStopped)
|
||||||
|
{
|
||||||
|
updateEnabled();
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
std::error_code Train::setTargetSpeed(Throttle& throttle, double value)
|
std::error_code Train::setTargetSpeed(Throttle& throttle, double value)
|
||||||
{
|
{
|
||||||
if(m_throttle.get() != &throttle)
|
if(m_throttle.get() != &throttle)
|
||||||
|
|||||||
@ -124,6 +124,7 @@ class Train : public IdObject
|
|||||||
std::string throttleName() const;
|
std::string throttleName() const;
|
||||||
std::error_code acquire(Throttle& throttle, bool steal = false);
|
std::error_code acquire(Throttle& throttle, bool steal = false);
|
||||||
std::error_code release(Throttle& throttle);
|
std::error_code release(Throttle& throttle);
|
||||||
|
std::error_code setSpeed(Throttle& throttle, double value);
|
||||||
std::error_code setTargetSpeed(Throttle& throttle, double value);
|
std::error_code setTargetSpeed(Throttle& throttle, double value);
|
||||||
std::error_code setDirection(Throttle& throttle, Direction value);
|
std::error_code setDirection(Throttle& throttle, Direction value);
|
||||||
|
|
||||||
|
|||||||
@ -35,10 +35,15 @@ function Throttle(parent, id)
|
|||||||
e.setAttribute('action', action);
|
e.setAttribute('action', action);
|
||||||
e.onclick = function ()
|
e.onclick = function ()
|
||||||
{
|
{
|
||||||
tm.send({
|
var msg = {
|
||||||
'throttle_id': parseInt(this.getAttribute('throttle-id')),
|
'throttle_id': parseInt(this.getAttribute('throttle-id')),
|
||||||
'action': this.getAttribute('action'),
|
'action': this.getAttribute('action'),
|
||||||
});
|
};
|
||||||
|
if(msg.action == 'faster' || msg.action == 'slower' || msg.action == 'stop')
|
||||||
|
{
|
||||||
|
msg.immediate = localStorage.immediateSpeedControl != 'false';
|
||||||
|
}
|
||||||
|
tm.send(msg);
|
||||||
};
|
};
|
||||||
return e;
|
return e;
|
||||||
};
|
};
|
||||||
@ -331,6 +336,10 @@ var tm = new function ()
|
|||||||
{
|
{
|
||||||
document.getElementById('stop_train_on_release').value = localStorage.throttleStopOnRelease;
|
document.getElementById('stop_train_on_release').value = localStorage.throttleStopOnRelease;
|
||||||
}
|
}
|
||||||
|
if(localStorage.immediateSpeedControl)
|
||||||
|
{
|
||||||
|
document.getElementById('immediate_speed_control').value = localStorage.immediateSpeedControl;
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('open_settings').onclick = function ()
|
document.getElementById('open_settings').onclick = function ()
|
||||||
{
|
{
|
||||||
@ -348,7 +357,8 @@ var tm = new function ()
|
|||||||
document.getElementById('close_settings').onclick = function ()
|
document.getElementById('close_settings').onclick = function ()
|
||||||
{
|
{
|
||||||
localStorage.throttleName = document.getElementById('throttle_name').value;
|
localStorage.throttleName = document.getElementById('throttle_name').value;
|
||||||
localStorage.throttleStopOnRelease = document.getElementById('stop_train_on_release').value == 'on';
|
localStorage.throttleStopOnRelease = document.getElementById('stop_train_on_release').checked;
|
||||||
|
localStorage.immediateSpeedControl = document.getElementById('immediate_speed_control').checked;
|
||||||
document.getElementById('settings').classList.add('hide');
|
document.getElementById('settings').classList.add('hide');
|
||||||
tm.connect();
|
tm.connect();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -24,6 +24,10 @@
|
|||||||
<label class="flex-resize">Stop train on release</label>
|
<label class="flex-resize">Stop train on release</label>
|
||||||
<input class="toggle_switch" type="checkbox" id="stop_train_on_release" checked="checked"><label class="toggle_switch" for="stop_train_on_release"></label>
|
<input class="toggle_switch" type="checkbox" id="stop_train_on_release" checked="checked"><label class="toggle_switch" for="stop_train_on_release"></label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex-row">
|
||||||
|
<label class="flex-resize">Immediate speed control</label>
|
||||||
|
<input class="toggle_switch" type="checkbox" id="immediate_speed_control" checked="checked"><label class="toggle_switch" for="immediate_speed_control"></label>
|
||||||
|
</div>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<button id="close_settings">Close</button>
|
<button id="close_settings">Close</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Laden…
x
In neuem Issue referenzieren
Einen Benutzer sperren