fix: compute ETA using measured tick rate

This commit is contained in:
2026-08-02 16:44:12 +08:00
parent ea288b6572
commit 23196cd59d
+25 -10
View File
@@ -2,7 +2,7 @@
-- ============================================================================ -- ============================================================================
-- 1. Configuration & Constants -- 1. Configuration & Constants
-- ============================================================================ -- ============================================================================
local APP_VERSION_TEXT = "v1.0.29" local APP_VERSION_TEXT = "v1.0.30"
local CONFIG = { local CONFIG = {
CLOUD_URL = "ws://stabadmin.fse-media.group", CLOUD_URL = "ws://stabadmin.fse-media.group",
@@ -51,7 +51,8 @@ local State = {
currentPlaying = nil, currentPlaying = nil,
currentPriority = -1, currentPriority = -1,
interruptSeq = 0, interruptSeq = 0,
debugUpcoming = nil debugUpcoming = nil,
tickRate = 20
} }
-- ============================================================================ -- ============================================================================
@@ -2139,11 +2140,12 @@ function Display.render()
mon.setTextColor(COLORS.DEBUG) mon.setTextColor(COLORS.DEBUG)
local dbg = State.debugUpcoming local dbg = State.debugUpcoming
local dbgLine = string.format( local dbgLine = string.format(
"SRC BR:%s CT:%s OK:%s TS:%s", "SRC BR:%s CT:%s OK:%s TS:%s TPS:%s",
dbg.hasBR and "Y" or "N", dbg.hasBR and "Y" or "N",
dbg.hasCT and "Y" or "N", dbg.hasCT and "Y" or "N",
dbg.ok and "Y" or "N", dbg.ok and "Y" or "N",
tostring(dbg.trainStopsCount or 0) tostring(dbg.trainStopsCount or 0),
tostring(math.floor((dbg.tickRate or 20) * 10) / 10)
) )
if #dbgLine > w then dbgLine = dbgLine:sub(1, w) end if #dbgLine > w then dbgLine = dbgLine:sub(1, w) end
mon.write(dbgLine) mon.write(dbgLine)
@@ -2333,7 +2335,8 @@ function Main.loop()
hasBR = Peripherals.blockReader ~= nil, hasBR = Peripherals.blockReader ~= nil,
hasCT = Peripherals.createTarget ~= nil, hasCT = Peripherals.createTarget ~= nil,
ok = false, ok = false,
trainStopsCount = 0 trainStopsCount = 0,
tickRate = State.tickRate or 20
} }
-- Check Block Reader (Advanced Peripherals) first for precise ETA and Delay -- Check Block Reader (Advanced Peripherals) first for precise ETA and Delay
@@ -2347,13 +2350,25 @@ function Main.loop()
for _ in pairs(data.TrainStops) do c = c + 1 end for _ in pairs(data.TrainStops) do c = c + 1 end
end end
dbg.trainStopsCount = c dbg.trainStopsCount = c
-- Real-time interpolation: calculate exact current tick even if NBT is cached -- Real-time interpolation: estimate actual tick rate (TPS) from CRN refreshes
if not State.lastRefreshed or State.lastRefreshed ~= data.LastRefreshed then if not State.lastRefreshed or State.lastRefreshed ~= data.LastRefreshed then
if State.lastRefreshed and State.lastRefreshedEpoch then
local deltaTicks = (data.LastRefreshed or 0) - (State.lastRefreshed or 0)
local deltaSeconds = (now - (State.lastRefreshedEpoch or now)) / 1000
if deltaTicks > 0 and deltaSeconds > 0 then
local rate = deltaTicks / deltaSeconds
if rate < 1 then rate = 1 end
if rate > 20 then rate = 20 end
State.tickRate = rate
end
end
State.lastRefreshed = data.LastRefreshed State.lastRefreshed = data.LastRefreshed
State.lastRefreshedEpoch = now State.lastRefreshedEpoch = now
end end
local elapsedTicks = math.floor((now - (State.lastRefreshedEpoch or now)) / 50) dbg.tickRate = State.tickRate or 20
local currentTick = (data.LastRefreshed or 0) + elapsedTicks
local elapsedSeconds = (now - (State.lastRefreshedEpoch or now)) / 1000
local currentTick = (data.LastRefreshed or 0) + math.floor(elapsedSeconds * (State.tickRate or 20))
for k, v in pairs(State.announcedApproaching) do for k, v in pairs(State.announcedApproaching) do
if now - v > 300000 then if now - v > 300000 then
@@ -2396,12 +2411,12 @@ function Main.loop()
local scheduledArrival = st.ScheduledArrival or 0 local scheduledArrival = st.ScheduledArrival or 0
local realArrival = st.RealTimeArrival or 0 local realArrival = st.RealTimeArrival or 0
local etaTicks = realArrival - currentTick local etaTicks = realArrival - currentTick
local etaSeconds = math.floor(etaTicks / 20) local etaSeconds = math.floor(etaTicks / (State.tickRate or 20))
if etaSeconds < 0 then etaSeconds = 0 end if etaSeconds < 0 then etaSeconds = 0 end
-- Calculate Delay in minutes -- Calculate Delay in minutes
local delayTicks = realArrival - scheduledArrival local delayTicks = realArrival - scheduledArrival
local delayMinutes = math.floor(delayTicks / (20 * 60)) local delayMinutes = math.floor(delayTicks / ((State.tickRate or 20) * 60))
if delayMinutes < 0 then delayMinutes = 0 end if delayMinutes < 0 then delayMinutes = 0 end
table.insert(newUpcoming, { table.insert(newUpcoming, {