mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-08 02:58:37 +01:00
fix(physics): running backwards, the camshaft goes back down from the last series position (eu07/maszyna#393) (#256)
Running backwards, AutoRelayCheck() keeps the camshaft from joining the motors in more branches than BackwardsBranchesAllowed (the series connection alone, by default). It did that by returning before any move of the camshaft, so once it reached the last series position (22 of 43 in the Skoda 181 and 182, the next one joins the motors in two branches) it stayed there whatever the driver did with the master controller: with the controller back at zero the line contactors stayed closed and the motors kept pulling, until the line contactors were opened by hand. Now the limit only keeps the camshaft from going further up; it goes back down as usual. Tests: tests/unit/test_camshaft.cpp, on a locomotive made after the Skoda 181 (its RList); the test definitions take the RList and MotorParamTable0 tables.
This commit is contained in:
@@ -6904,13 +6904,12 @@ bool TMoverParameters::AutoRelayCheck(void)
|
||||
}
|
||||
else
|
||||
{ // zmieniaj mainctrlactualpos
|
||||
if (DirActive < 0 && TrainType != dt_PseudoDiesel && RList[MainCtrlActualPos + 1].Bn > BackwardsBranchesAllowed)
|
||||
{
|
||||
return false; // nie poprawiamy przy konwersji
|
||||
// return ARC;// bbylo exit; //Ra: to powoduje, że EN57 nie wyłącza się przy IminLo
|
||||
}
|
||||
// running backwards, the motors don't get joined in more branches than allowed (the series connection
|
||||
// alone, usually); the camshaft still goes back down from there (eu07/maszyna#393: it stayed where it
|
||||
// was, the line contactors closed, whatever the driver did with the master controller)
|
||||
auto const backwardslimit{DirActive < 0 && TrainType != dt_PseudoDiesel && RList[MainCtrlActualPos + 1].Bn > BackwardsBranchesAllowed};
|
||||
// main bez samoczynnego rozruchu
|
||||
if (MainCtrlActualPos < std::size(RList) - 1 // crude guard against running out of current fixed table
|
||||
if (false == backwardslimit && MainCtrlActualPos < std::size(RList) - 1 // crude guard against running out of current fixed table
|
||||
&& (RList[MainCtrlActualPos].Relay < MainCtrlPos || (RList[MainCtrlActualPos + 1].Relay == MainCtrlPos && MainCtrlActualPos < RlistSize) ||
|
||||
(TrainType == dt_ET22 && DelayCtrlFlag)))
|
||||
{
|
||||
|
||||
135
tests/unit/test_camshaft.cpp
Normal file
135
tests/unit/test_camshaft.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#include "stdafx.h"
|
||||
#include "doctest.h"
|
||||
#include "vehicle.h"
|
||||
|
||||
using test::definition;
|
||||
using test::vehicle;
|
||||
|
||||
// eu07/maszyna#393: running backwards, a camshaft which reached the last position of the series connection (the
|
||||
// next one already joins the motors in more branches than BackwardsBranchesAllowed) stayed there whatever the driver
|
||||
// did with the master controller, with the line contactors closed and the motors pulling, until the line contactors
|
||||
// were opened by hand
|
||||
|
||||
namespace {
|
||||
|
||||
// the starting resistances of the Skoda 181 (cd/181_v2): 6 motors in series up to position 22, then two branches of
|
||||
// 3 up to 34, then three branches of 2 up to 43; columns: position, resistance, branches, motors in a branch, auto
|
||||
nlohmann::ordered_json skoda_rlist() {
|
||||
nlohmann::ordered_json rows{nlohmann::ordered_json::array({0, 0, 0, 0, 0}), nlohmann::ordered_json::array({1, 999999, 1, 6, 0})};
|
||||
auto const series{std::vector<double>{15.87, 12.32, 10.03, 8.54, 6.98, 5.84, 5.35, 4.87, 3.88, 2.92, 2.68, 2.43, 2.19, 1.95, 1.70, 1.46, 1.22, 0.97, 0.49, 0.24, 0.00}};
|
||||
auto const seriesparallel{std::vector<double>{4.50, 3.63, 3.11, 2.42, 2.08, 1.73, 1.38, 1.04, 0.69, 0.35, 0.17, 0.00}};
|
||||
auto const parallel{std::vector<double>{2.78, 2.29, 1.80, 1.41, 1.02, 0.73, 0.44, 0.24, 0.00}};
|
||||
auto position{2};
|
||||
for (auto const resistance : series) {
|
||||
rows.push_back(nlohmann::ordered_json::array({position++, resistance, 1, 6, 0}));
|
||||
}
|
||||
for (auto const resistance : seriesparallel) {
|
||||
rows.push_back(nlohmann::ordered_json::array({position++, resistance, 2, 3, 0}));
|
||||
}
|
||||
for (auto const resistance : parallel) {
|
||||
rows.push_back(nlohmann::ordered_json::array({position++, resistance, 3, 2, 0}));
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
// an electric locomotive with a camshaft, made after the Skoda 181
|
||||
definition skoda() {
|
||||
auto result{definition::load("wagon")
|
||||
.set("Param", "M", 124200)
|
||||
.set("Param", "Vmax", 90)
|
||||
.set("Dimensions", "L", 18.8)
|
||||
.set("Wheels", "D", 1.25)
|
||||
.set("Wheels", "Axle", "Co'Co'")
|
||||
.set("Engine", "EngineType", "ElectricSeriesMotor")
|
||||
.set("Engine", "Volt", 967)
|
||||
.set("Engine", "Trans", "21:89")
|
||||
.set("Engine", "WindingRes", 0.084)
|
||||
.set("Engine", "nmax", 1870)
|
||||
.set("Circuit", "CircuitRes", 0.01)
|
||||
.set("Circuit", "ImaxLo", 550)
|
||||
.set("Circuit", "ImaxHi", 550)
|
||||
.set("Circuit", "IminLo", 307)
|
||||
.set("Circuit", "IminHi", 332)
|
||||
.set("Cntrl", "MCPN", 43)
|
||||
.set("Cntrl", "SCPN", 3)
|
||||
.set("Cntrl", "CoupledCtrl", "No")
|
||||
.set("Cntrl", "IniCDelay", 0.2)
|
||||
.set("Cntrl", "SCDelay", 0.18)
|
||||
.set("Cntrl", "SCDDelay", 0.18)
|
||||
.set("Cntrl", "Camshaft", "Yes")
|
||||
.set("MotorParamTable0", "rows",
|
||||
nlohmann::ordered_json::array({nlohmann::ordered_json::array({0, 33.75, 57, 0.4, 225.70, 57, 0.4}), nlohmann::ordered_json::array({1, 31.66, 69, 0.4, 217.10, 69, 0.4}),
|
||||
nlohmann::ordered_json::array({2, 30.52, 90, 0.4, 212.80, 90, 0.4}), nlohmann::ordered_json::array({3, 28.74, 107, 0.4, 199.55, 107, 0.4})}))
|
||||
.set("RList", "Size", 43)
|
||||
.set("RList", "rows", skoda_rlist())};
|
||||
return result;
|
||||
}
|
||||
|
||||
// the locomotive running with the line contactors closed and the camshaft at Position, the master controller moved
|
||||
// to Controller, in the given direction; the time since the last step of the camshaft long enough for the next one
|
||||
void running(TMoverParameters &Locomotive, int const Direction, int const Position, int const Controller) {
|
||||
Locomotive.CabActive = 1;
|
||||
Locomotive.DirActive = Direction;
|
||||
Locomotive.Mains = true;
|
||||
Locomotive.PipePress = 5.0; // bar, the pressure switch lets the line contactors close
|
||||
Locomotive.BrakePress = 0.0;
|
||||
Locomotive.StLinFlag = true;
|
||||
Locomotive.MainCtrlActualPos = Position;
|
||||
Locomotive.MainCtrlPos = Controller;
|
||||
Locomotive.LastRelayTime = 10.0;
|
||||
}
|
||||
|
||||
// steps the camshaft as the physics does, each step once the delay since the previous one passed; returns where it
|
||||
// ended up
|
||||
int run_camshaft(TMoverParameters &Locomotive, int const Steps) {
|
||||
for (int step = 0; step < Steps; ++step) {
|
||||
Locomotive.LastRelayTime = 10.0;
|
||||
Locomotive.AutoRelayCheck();
|
||||
}
|
||||
return Locomotive.MainCtrlActualPos;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("camshaft: running backwards, the camshaft goes back down from the last series position (eu07/maszyna#393)") {
|
||||
vehicle locomotive{skoda()};
|
||||
auto &mover{locomotive.mover()};
|
||||
REQUIRE(mover.HasCamshaft);
|
||||
REQUIRE(mover.RlistSize == 43);
|
||||
REQUIRE(mover.RList[22].Bn == 1);
|
||||
REQUIRE(mover.RList[23].Bn == 2);
|
||||
|
||||
SUBCASE("the controller turned back a few positions") {
|
||||
running(mover, -1, 22, 15);
|
||||
CHECK(run_camshaft(mover, 1) == 21); // it used to stay at 22
|
||||
CHECK(run_camshaft(mover, 10) == 15);
|
||||
}
|
||||
SUBCASE("the controller turned back to zero: the camshaft runs down and the line contactors open") {
|
||||
running(mover, -1, 22, 0);
|
||||
run_camshaft(mover, 30);
|
||||
CHECK(mover.MainCtrlActualPos == 0);
|
||||
CHECK_FALSE(mover.StLinFlag); // the motors don't pull any more
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("camshaft: running backwards, the camshaft still doesn't go past the series connection") {
|
||||
vehicle locomotive{skoda()};
|
||||
auto &mover{locomotive.mover()};
|
||||
running(mover, -1, 20, 43);
|
||||
CHECK(run_camshaft(mover, 10) == 22);
|
||||
|
||||
SUBCASE("unless more branches are allowed backwards") {
|
||||
mover.BackwardsBranchesAllowed = 2;
|
||||
CHECK(run_camshaft(mover, 20) == 34);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("camshaft: running forwards, the camshaft goes through all the connections and back") {
|
||||
vehicle locomotive{skoda()};
|
||||
auto &mover{locomotive.mover()};
|
||||
running(mover, 1, 20, 43);
|
||||
CHECK(run_camshaft(mover, 30) == 43);
|
||||
|
||||
mover.MainCtrlPos = 10;
|
||||
CHECK(run_camshaft(mover, 40) == 10);
|
||||
}
|
||||
@@ -45,6 +45,8 @@ std::map<std::string, section_format, std::less<>> const sections{
|
||||
{"DimmerList", {':', "endDimmerList"}},
|
||||
{"WiperList", {':', "endwl"}},
|
||||
{"CompressorList", {':', "endCL"}},
|
||||
{"RList", {':', "END-RL"}},
|
||||
{"MotorParamTable0", {':', "END-MPT"}},
|
||||
};
|
||||
|
||||
section_format const &format_of(std::string const &Section) {
|
||||
|
||||
Reference in New Issue
Block a user