aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorywang <yw05@forksworld.de>2019-12-03 22:46:36 +0100
committerywang <yw05@forksworld.de>2019-12-03 22:46:36 +0100
commitcee62d7e175b73ae4ea08a0bebccaac1e0df043f (patch)
tree6410d26c428a944c986c8402749e65cbaff04494
parent25a335203f81fb80effed30f74aed2ed7d488837 (diff)
downloadadvtrains-cee62d7e175b73ae4ea08a0bebccaac1e0df043f.tar.gz
advtrains-cee62d7e175b73ae4ea08a0bebccaac1e0df043f.tar.bz2
advtrains-cee62d7e175b73ae4ea08a0bebccaac1e0df043f.zip
Add function to calculate distance until override
The function will be used to improve the train movement algorithm. The changes related to spaces in blank lines is caused by a weird feature in the text editor.
-rw-r--r--advtrains/lzb.lua77
1 files changed, 62 insertions, 15 deletions
diff --git a/advtrains/lzb.lua b/advtrains/lzb.lua
index 6cbf4ab..461e863 100644
--- a/advtrains/lzb.lua
+++ b/advtrains/lzb.lua
@@ -47,19 +47,19 @@ end
local function look_ahead(id, train)
-
+
local acc = advtrains.get_acceleration(train, 1)
local vel = train.velocity
local brakedst = ( -(vel*vel) / (2*acc) ) * params.DST_FACTOR
-
+
local brake_i = advtrains.path_get_index_by_offset(train, train.index, brakedst + params.BRAKE_SPACE)
--local aware_i = advtrains.path_get_index_by_offset(train, brake_i, AWARE_ZONE)
-
+
local lzb = train.lzb
local trav = lzb.trav
-
+
--train.debug = lspd
-
+
while trav <= brake_i do
trav = trav + 1
local pos = advtrains.path_get(train, trav)
@@ -74,12 +74,12 @@ local function look_ahead(id, train)
-- run callbacks
-- Note: those callbacks are defined in trainlogic.lua for consistency with the other node callbacks
advtrains.tnc_call_approach_callback(pos, id, train, trav, lzb.data)
-
+
end
end
-
+
lzb.trav = trav
-
+
end
--[[
@@ -92,7 +92,7 @@ s = v0 * ------- + - * | ------- | = -----------
local function apply_control(id, train)
local lzb = train.lzb
-
+
local i = 1
while i<=#lzb.oncoming do
if lzb.oncoming[i].idx < train.index then
@@ -100,20 +100,20 @@ local function apply_control(id, train)
if ent.fun then
ent.fun(ent.pos, id, train, ent.idx, ent.spd, lzb.data)
end
-
+
table.remove(lzb.oncoming, i)
else
i = i + 1
end
end
-
+
for i, it in ipairs(lzb.oncoming) do
local a = advtrains.get_acceleration(train, 1) --should be negative
local v0 = train.velocity
local v1 = it.spd
if v1 and v1 <= v0 then
local s = (v1*v1 - v0*v0) / (2*a)
-
+
local st = s + params.ADD_SLOW
if v0 > 3 then
st = s + params.ADD_FAST
@@ -121,9 +121,9 @@ local function apply_control(id, train)
if v0<=0 then
st = s + params.ADD_STAND
end
-
+
local i = advtrains.path_get_index_by_offset(train, it.idx, -st)
-
+
--train.debug = dump({v0f=v0*f, aff=a*f*f,v0=v0, v1=v1, f=f, a=a, s=s, st=st, i=i, idx=train.index})
if i <= train.index then
-- Gotcha! Braking...
@@ -131,7 +131,7 @@ local function apply_control(id, train)
--train.debug = train.debug .. "BRAKE!!!"
return
end
-
+
i = advtrains.path_get_index_by_offset(train, i, -params.ZONE_ROLL)
if i <= train.index and v0>1 then
-- roll control
@@ -149,6 +149,53 @@ local function apply_control(id, train)
train.ctrl.lzb = nil
end
+-- Get the distance between the train and the LZB control point
+-- If not sure, use 3 as the parameter for lever level.
+function advtrains.lzb_get_distance_until_override(id, train, lever)
+ if lever == 4 then return nil end -- acceleration can not be forced by LZB
+ local lzb = train.lzb
+ local i = 1
+ local ret = nil -- the value to return
+ -- Remove LZB entries that are no longer valid
+ while i <= #lzb.oncoming do
+ if lzb.oncoming[i].idx < train.index then
+ local ent = lzb.oncoming[i]
+ if ent.fun then
+ ent.fun(ent.pos, id, train, ent.idx, ent.spd, lzb.data)
+ end
+ table.remove(lzb.oncoming, i)
+ else
+ i = i + 1
+ end
+ end
+ -- Now run through all the LZB entries and find the one that is nearest to the train
+ for _, it in ipairs(lzb.oncoming) do
+ local a = advtrains.get_acceleration(train, lever)
+ local v0 = train.velocity
+ local v1 = it.spd
+ if v1 and v1 <= v0 then
+ if a !~ 0 then local s = (v1*v1-v0*)/2/a else s = 0 end
+ local st
+ if v0 > 3 then st = s + params.ADD_FAST
+ elseif v0 <= 0 then st = s + params.ADD_STAND
+ else st = s + params.ADD_SLOW
+ end
+ i = advtrains.path_get_index_by_offset(train, it.idx, -st)
+ if lever == 2 then
+ i = advtrains.path_get_index_by_offset(train, it.idx, -params.ZONE_ROLL)
+ end
+ if lever == 3 then
+ i = advtrains.path_get_index_by_offset(train, id.idx, -params.ZONE_HOLD)
+ end
+ if not ret then ret = i - train.index end
+ if (i - train.index) < ret then ret = i - train.index end
+ end
+ end
+ -- In extreme cases, there might be no LZB at all.
+ -- In such a case, return nil because the distance to LZB is infinite.
+ return ret
+end
+
local function invalidate(train)
train.lzb = {
trav = atfloor(train.index),