summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcheapie <no-email-for-you@example.com>2024-04-20 10:09:38 -0500
committercheapie <no-email-for-you@example.com>2024-04-20 10:09:38 -0500
commit9ef3620f6f29ba4ac10dcc8ea56daa3fa4908c56 (patch)
tree85182140898a19bfb86a4c63c9cf6b26255b5924
parent0dd7fc056ace58af9c66e562ca612c36bbca3343 (diff)
downloadcelevator-9ef3620f6f29ba4ac10dcc8ea56daa3fa4908c56.tar
celevator-9ef3620f6f29ba4ac10dcc8ea56daa3fa4908c56.tar.gz
celevator-9ef3620f6f29ba4ac10dcc8ea56daa3fa4908c56.tar.bz2
celevator-9ef3620f6f29ba4ac10dcc8ea56daa3fa4908c56.tar.xz
celevator-9ef3620f6f29ba4ac10dcc8ea56daa3fa4908c56.zip
Improve dispatching algorithm
-rw-r--r--controllerfw.lua4
-rw-r--r--dispatcherfw.lua131
2 files changed, 122 insertions, 13 deletions
diff --git a/controllerfw.lua b/controllerfw.lua
index 190d595..c2a3449 100644
--- a/controllerfw.lua
+++ b/controllerfw.lua
@@ -608,6 +608,10 @@ elseif event.type == "dispatchermsg" then
mem.groupupcalls[event.msg] = true
elseif event.channel == "groupdncall" and mem.carstate == "normal" then
mem.groupdncalls[event.msg] = true
+ elseif event.channel == "groupupcancel" then
+ mem.groupupcalls[event.msg] = nil
+ elseif event.channel == "groupdncancel" then
+ mem.groupdncalls[event.msg] = nil
elseif event.channel == "carcall" and mem.carstate == "normal" then
mem.carcalls[event.msg] = true
send(event.source,"status",mem)
diff --git a/dispatcherfw.lua b/dispatcherfw.lua
index 5ee6364..1314eb7 100644
--- a/dispatcherfw.lua
+++ b/dispatcherfw.lua
@@ -29,6 +29,26 @@ local function getpos(carid)
return 1
end
+local function getdpos(carid)
+ local floormap = {}
+ local floorheights = {}
+ for i=1,#mem.params.floornames,1 do
+ if mem.params.floorsserved[carid][i] then
+ table.insert(floormap,i)
+ table.insert(floorheights,mem.params.floorheights[i])
+ elseif #floorheights > 0 then
+ floorheights[#floorheights] = floorheights[#floorheights]+mem.params.floorheights[i]
+ end
+ end
+ local ret = 0
+ local searchpos = mem.carstatus[carid].target
+ for k,v in ipairs(floorheights) do
+ ret = ret+v
+ if ret > searchpos then return floormap[k] end
+ end
+ return 1
+end
+
local function cartorealfloor(carid,floor)
if type(floor) == "table" then
local ret = {}
@@ -206,6 +226,12 @@ local function buildstopsequence(carid,startfloor,direction,target,targetdir)
end
local carpos = startfloor
local sequence = {}
+ local vel = mem.carstatus[carid].vel
+ if vel > 0 then
+ direction = "up"
+ elseif vel < 0 then
+ direction = "down"
+ end
repeat
local src = carpos
carpos,direction = predictnextstop(carid,carpos,direction,carcalls,upcalls,dncalls)
@@ -447,6 +473,7 @@ elseif event.channel == "pairok" then
carcalls = {},
doorstate = event.msg.doorstate,
position = event.msg.drive.status.apos or 0,
+ target = event.msg.drive.status.dpos or 0,
state = event.msg.carstate,
direction = event.msg.direction,
vel = event.msg.drive.status.vel or 0,
@@ -467,6 +494,7 @@ elseif event.channel == "status" then
carcalls = event.msg.carcalls,
doorstate = event.msg.doorstate,
position = event.msg.drive.status.apos or 0,
+ target = event.msg.drive.status.dpos or 0,
state = event.msg.carstate,
direction = event.msg.direction,
vel = event.msg.drive.status.vel,
@@ -530,12 +558,50 @@ elseif event.type == "abm" or event.iid == "run" then
mem.upcalls[i] = nil
end
end
+ for i in pairs(mem.assignedup) do
+ if mem.upcalls[i] then
+ local eligiblecars = {}
+ local permanent = false
+ for _,carid in pairs(mem.params.carids) do
+ if getdpos(carid) == i and mem.carstatus[carid].direction == "up" then permanent = true end
+ if mem.carstatus[carid].state == "normal" and mem.params.floorsserved[carid][i] then
+ local serveshigher = false
+ for floor in pairs(mem.params.floorsserved[carid]) do
+ if floor > i then
+ serveshigher = true
+ break
+ end
+ end
+ if serveshigher then eligiblecars[carid] = true end
+ end
+ end
+ if not permanent then
+ local besteta = 999
+ local bestcar
+ for carid in pairs(eligiblecars) do
+ local eta = calculateeta(carid,i,"up")
+ if eta < besteta then
+ besteta = eta
+ bestcar = carid
+ end
+ end
+ if mem.upeta[i]-besteta > 15 and mem.upeta[i]/besteta > 2 then
+ send(mem.assignedup[i],"groupupcancel",realtocarfloor(mem.assignedup[i],i))
+ mem.upeta[i] = besteta
+ send(bestcar,"groupupcall",realtocarfloor(bestcar,i))
+ mem.assignedup[i] = bestcar
+ end
+ end
+ end
+ end
for floor,carid in pairs(mem.assignedup) do
mem.upeta[floor] = calculateeta(carid,floor,"up")
end
for i in pairs(unassigneddn) do
local eligiblecars = {}
+ local permanent = false
for _,carid in pairs(mem.params.carids) do
+ if getdpos(carid) == i and mem.carstatus[carid].direction == "down" then permanent = true end
if mem.carstatus[carid].state == "normal" and mem.params.floorsserved[carid][i] then
local serveslower = false
for floor in pairs(mem.params.floorsserved[carid]) do
@@ -547,21 +613,55 @@ elseif event.type == "abm" or event.iid == "run" then
if serveslower then eligiblecars[carid] = true end
end
end
- local besteta = 999
- local bestcar
- for carid in pairs(eligiblecars) do
- local eta = calculateeta(carid,i,"down")
- if eta < besteta then
- besteta = eta
- bestcar = carid
+ if not permanent then
+ local besteta = 999
+ local bestcar
+ for carid in pairs(eligiblecars) do
+ local eta = calculateeta(carid,i,"down")
+ if eta < besteta then
+ besteta = eta
+ bestcar = carid
+ end
+ end
+ mem.upeta[i] = besteta
+ if bestcar then
+ send(bestcar,"groupdncall",realtocarfloor(bestcar,i))
+ mem.assigneddn[i] = bestcar
+ else
+ mem.dncalls[i] = nil
end
end
- mem.upeta[i] = besteta
- if bestcar then
- send(bestcar,"groupdncall",realtocarfloor(bestcar,i))
- mem.assigneddn[i] = bestcar
- else
- mem.upcalls[i] = nil
+ end
+ for i in pairs(mem.assigneddn) do
+ if mem.dncalls[i] then
+ local eligiblecars = {}
+ for _,carid in pairs(mem.params.carids) do
+ if mem.carstatus[carid].state == "normal" and mem.params.floorsserved[carid][i] then
+ local serveslower = false
+ for floor in pairs(mem.params.floorsserved[carid]) do
+ if floor < i then
+ serveslower = true
+ break
+ end
+ end
+ if serveslower then eligiblecars[carid] = true end
+ end
+ end
+ local besteta = 999
+ local bestcar
+ for carid in pairs(eligiblecars) do
+ local eta = calculateeta(carid,i,"down")
+ if eta < besteta then
+ besteta = eta
+ bestcar = carid
+ end
+ end
+ if mem.dneta[i]-besteta > 15 and mem.dneta[i]/besteta > 2 then
+ send(mem.assigneddn[i],"groupdncancel",realtocarfloor(mem.assigneddn[i],i))
+ mem.dneta[i] = besteta
+ send(bestcar,"groupdncall",realtocarfloor(bestcar,i))
+ mem.assigneddn[i] = bestcar
+ end
end
end
for floor,carid in pairs(mem.assigneddn) do
@@ -732,6 +832,11 @@ elseif mem.screenstate == "status" then
local carfloor = realtocarfloor(carid,floor)
if carfloor then
local ccdot = mem.carstatus[carid].carcalls[carfloor] and "*" or ""
+ local groupup = mem.carstatus[carid].groupupcalls[carfloor] and minetest.colorize("#55FF55","^") or ""
+ local swingup = mem.carstatus[carid].swingupcalls[carfloor] and minetest.colorize("#FFFF55","^") or ""
+ local swingdn = mem.carstatus[carid].swingdncalls[carfloor] and minetest.colorize("#FFFF55","v") or ""
+ local groupdn = mem.carstatus[carid].groupdncalls[carfloor] and minetest.colorize("#FF5555","v") or ""
+ ccdot = groupup..swingup..ccdot..swingdn..groupdn
if getpos(carid) == floor then
local cargraphics = {
open = "\\[ \\]",