fix: compute ETA using measured tick rate
This commit is contained in:
+25
-10
@@ -2,7 +2,7 @@
|
||||
-- ============================================================================
|
||||
-- 1. Configuration & Constants
|
||||
-- ============================================================================
|
||||
local APP_VERSION_TEXT = "v1.0.29"
|
||||
local APP_VERSION_TEXT = "v1.0.30"
|
||||
|
||||
local CONFIG = {
|
||||
CLOUD_URL = "ws://stabadmin.fse-media.group",
|
||||
@@ -51,7 +51,8 @@ local State = {
|
||||
currentPlaying = nil,
|
||||
currentPriority = -1,
|
||||
interruptSeq = 0,
|
||||
debugUpcoming = nil
|
||||
debugUpcoming = nil,
|
||||
tickRate = 20
|
||||
}
|
||||
|
||||
-- ============================================================================
|
||||
@@ -2139,11 +2140,12 @@ function Display.render()
|
||||
mon.setTextColor(COLORS.DEBUG)
|
||||
local dbg = State.debugUpcoming
|
||||
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.hasCT 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
|
||||
mon.write(dbgLine)
|
||||
@@ -2333,7 +2335,8 @@ function Main.loop()
|
||||
hasBR = Peripherals.blockReader ~= nil,
|
||||
hasCT = Peripherals.createTarget ~= nil,
|
||||
ok = false,
|
||||
trainStopsCount = 0
|
||||
trainStopsCount = 0,
|
||||
tickRate = State.tickRate or 20
|
||||
}
|
||||
|
||||
-- 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
|
||||
end
|
||||
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 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.lastRefreshedEpoch = now
|
||||
end
|
||||
local elapsedTicks = math.floor((now - (State.lastRefreshedEpoch or now)) / 50)
|
||||
local currentTick = (data.LastRefreshed or 0) + elapsedTicks
|
||||
dbg.tickRate = State.tickRate or 20
|
||||
|
||||
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
|
||||
if now - v > 300000 then
|
||||
@@ -2396,12 +2411,12 @@ function Main.loop()
|
||||
local scheduledArrival = st.ScheduledArrival or 0
|
||||
local realArrival = st.RealTimeArrival or 0
|
||||
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
|
||||
|
||||
-- Calculate Delay in minutes
|
||||
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
|
||||
|
||||
table.insert(newUpcoming, {
|
||||
|
||||
Reference in New Issue
Block a user