Add LuaAutomation interface functions for interlocking routesetting and aspect requesting.
This allows to incorporate interlocking to automated systems
This commit is contained in:
parent
5039c958a2
commit
d837e7e5e9
|
@ -364,5 +364,5 @@ minetest.register_chatcommand("at_rp_discard",
|
||||||
|
|
||||||
|
|
||||||
--TODO on route setting
|
--TODO on route setting
|
||||||
-- unify luaautomation get/setstate interface to the core
|
|
||||||
-- routes should end at signals. complete route setting by punching a signal, and command as exceptional route completion
|
-- routes should end at signals. complete route setting by punching a signal, and command as exceptional route completion
|
||||||
|
-- Create simpler way to advance a route to the next tcb/signal on simple sections without turnouts
|
||||||
|
|
|
@ -20,13 +20,6 @@ ilrs.rte_callbacks = {
|
||||||
lck = {}
|
lck = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Requests the given route
|
|
||||||
-- This function will try to set the designated route.
|
|
||||||
-- If this is not possible, route is inserted in the subscriber list for
|
|
||||||
-- the problematic lock points
|
|
||||||
function ilrs.request_route(signal, tcbs, routeid)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
-- main route setting. First checks if everything can be set as designated,
|
-- main route setting. First checks if everything can be set as designated,
|
||||||
-- then (if "try" is not set) actually sets it
|
-- then (if "try" is not set) actually sets it
|
||||||
|
|
|
@ -55,17 +55,20 @@ Every attempt to overwrite any of the predefined values results in an error.
|
||||||
POS(x,y,z)
|
POS(x,y,z)
|
||||||
Shorthand function to create a position vector {x=?, y=?, z=?} with less characters
|
Shorthand function to create a position vector {x=?, y=?, z=?} with less characters
|
||||||
|
|
||||||
|
In the following functions, all parameters named 'pos' designate a position. You can use either:
|
||||||
|
- a default Minetest position vector (like {x=34, y=2, z=-18})
|
||||||
|
- the POS(34,2,-18) shorthand
|
||||||
|
- A string, the passive component name. See 'passive component naming'.
|
||||||
|
|
||||||
getstate(pos)
|
getstate(pos)
|
||||||
Get the state of the passive component at position 'pos'. See section on passive components for more info.
|
Get the state of the passive component at position 'pos'. See section on passive components for more info.
|
||||||
pos can be either a position vector (created by POS()) or a string, the name of this passive component.
|
pos can be either a position vector (created by POS()) or a string, the name of this passive component.
|
||||||
|
|
||||||
setstate(pos, newstate)
|
setstate(pos, newstate)
|
||||||
Set the state of the passive component at position 'pos'.
|
Set the state of the passive component at position 'pos'.
|
||||||
pos can be either a position vector (created by POS()) or a string, the name of this passive component.
|
|
||||||
|
|
||||||
is_passive(pos)
|
is_passive(pos)
|
||||||
Checks whether there is a passive component at the position pos (and/or whether a passive component with this name exists)
|
Checks whether there is a passive component at the position pos (and/or whether a passive component with this name exists)
|
||||||
pos can be either a position vector (created by POS()) or a string, the name of this passive component.
|
|
||||||
|
|
||||||
interrupt(time, message)
|
interrupt(time, message)
|
||||||
Cause LuaAutomation to trigger an 'int' event on this component after the given time in seconds with the specified 'message' field. 'message' can be of any Lua data type.
|
Cause LuaAutomation to trigger an 'int' event on this component after the given time in seconds with the specified 'message' field. 'message' can be of any Lua data type.
|
||||||
|
@ -79,6 +82,38 @@ digiline_send(channel, message)
|
||||||
Make this active component send a digiline message on the specified channel.
|
Make this active component send a digiline message on the specified channel.
|
||||||
Not available in init code!
|
Not available in init code!
|
||||||
|
|
||||||
|
-- The next 4 functions are available when advtrains_interlocking is enabled: --
|
||||||
|
|
||||||
|
can_set_route(pos, route_name)
|
||||||
|
Returns whether it is possible to set the route designated by route_name from the signal at pos.
|
||||||
|
|
||||||
|
set_route(pos, route_name)
|
||||||
|
Requests the given route from the signal at pos. Has the same effect as clicking "Set Route" in the signalling dialog.
|
||||||
|
|
||||||
|
cancel_route(pos)
|
||||||
|
Cancels the route that is set from the signal at pos. Has the same effect as clicking "Cancel Route" in the signalling dialog.
|
||||||
|
|
||||||
|
get_aspect(pos)
|
||||||
|
Returns the signal aspect of the signal at pos. A signal aspect has the following format:
|
||||||
|
aspect = {
|
||||||
|
main = { -- the next track section in line. Shows blocked for shunt routes
|
||||||
|
free = <boolean>,
|
||||||
|
speed = <int km/h>,
|
||||||
|
},
|
||||||
|
shunt = { -- whether a "shunting allowed" aspect should be shown
|
||||||
|
free = <boolean>,
|
||||||
|
}
|
||||||
|
dst = { -- the aspect of the next main signal on (at end of) route
|
||||||
|
free = <boolean>,
|
||||||
|
speed = <int km/h>,
|
||||||
|
}
|
||||||
|
info = {
|
||||||
|
call_on = <boolean>, -- Call-on route, expect train in track ahead
|
||||||
|
dead_end = <boolean>, -- Route ends on a dead end (e.g. bumper)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
As of August 2018, only the aspect.main.free field is ever used by the interlocking system.
|
||||||
|
|
||||||
## Components and events
|
## Components and events
|
||||||
|
|
||||||
The event table is a table of the following format:
|
The event table is a table of the following format:
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
advtrains
|
advtrains
|
||||||
|
advtrains_interlocking?
|
||||||
mesecons_switch?
|
mesecons_switch?
|
|
@ -154,14 +154,65 @@ local static_env = {
|
||||||
--however external interrupts can be set here.
|
--however external interrupts can be set here.
|
||||||
interrupt_pos = function(parpos, imesg)
|
interrupt_pos = function(parpos, imesg)
|
||||||
local pos=atlatc.pcnaming.resolve_pos(parpos)
|
local pos=atlatc.pcnaming.resolve_pos(parpos)
|
||||||
if not type(pos)=="table" or not pos.x or not pos.y or not pos.z then
|
|
||||||
debug.sethook()
|
|
||||||
error("Invalid position supplied to interrupt_pos")
|
|
||||||
end
|
|
||||||
atlatc.interrupt.add(0, pos, {type="ext_int", ext_int=true, message=imesg})
|
atlatc.interrupt.add(0, pos, {type="ext_int", ext_int=true, message=imesg})
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- If interlocking is present, enable route setting functions
|
||||||
|
if advtrains.interlocking then
|
||||||
|
local function gen_checks(signal, route_name, noroutesearch)
|
||||||
|
assertt(route_name, "string")
|
||||||
|
local pos = atlatc.pcnaming.resolve_pos(signal)
|
||||||
|
local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos)
|
||||||
|
if not sigd then
|
||||||
|
error("There's no signal at "..minetest.pos_to_string(pos))
|
||||||
|
end
|
||||||
|
local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
|
||||||
|
if not tcbs then
|
||||||
|
error("Inconsistent configuration, no tcbs for signal at "..minetest.pos_to_string(pos))
|
||||||
|
end
|
||||||
|
|
||||||
|
local routeid, route
|
||||||
|
if not noroutesearch then
|
||||||
|
for routeidt, routet in ipairs(tcbs.routes) do
|
||||||
|
if routet.name == route_name then
|
||||||
|
routeid = routeidt
|
||||||
|
route = routet
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not route then
|
||||||
|
error("No route called "..route_name.." at "..minetest.pos_to_string(pos))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return pos, sigd, tcbs, routeid, route
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
static_env.can_set_route = function(signal, route_name)
|
||||||
|
local pos, sigd, tcbs, routeid, route = gen_checks(signal, route_name)
|
||||||
|
-- if route is already set on signal, return whether it's committed
|
||||||
|
if tcbs.routeset == routeid then
|
||||||
|
return tcbs.route_committed
|
||||||
|
end
|
||||||
|
-- actually try setting route (parameter 'true' designates try-run
|
||||||
|
local ok = advtrains.interlocking.route.set_route(sigd, route, true)
|
||||||
|
return ok
|
||||||
|
end
|
||||||
|
static_env.set_route = function(signal, route_name)
|
||||||
|
local pos, sigd, tcbs, routeid, route = gen_checks(signal, route_name)
|
||||||
|
return advtrains.interlocking.route.update_route(sigd, tcbs, routeid)
|
||||||
|
end
|
||||||
|
static_env.cancel_route = function(signal)
|
||||||
|
local pos, sigd, tcbs, routeid, route = gen_checks(signal, "", true)
|
||||||
|
return advtrains.interlocking.route.update_route(sigd, tcbs, nil, true)
|
||||||
|
end
|
||||||
|
static_env.get_aspect = function(signal)
|
||||||
|
local pos = atlatc.pcnaming.resolve_pos(signal)
|
||||||
|
return advtrains.interlocking.signal_get_aspect(pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
for _, name in pairs(safe_globals) do
|
for _, name in pairs(safe_globals) do
|
||||||
static_env[name] = _G[name]
|
static_env[name] = _G[name]
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,9 +12,14 @@ function atlatc.pcnaming.save()
|
||||||
return atlatc.pcnaming.name_map
|
return atlatc.pcnaming.name_map
|
||||||
end
|
end
|
||||||
|
|
||||||
function atlatc.pcnaming.resolve_pos(posorname)
|
function atlatc.pcnaming.resolve_pos(pos, func_name)
|
||||||
if type(posorname)=="table" then return posorname end
|
if type(pos)=="string" then
|
||||||
return atlatc.pcnaming.name_map[posorname]
|
local e = atlatc.pcnaming.name_map[pos]
|
||||||
|
if e then return e end
|
||||||
|
elseif type(pos)=="table" and pos.x and pos.y and pos.z then
|
||||||
|
return pos
|
||||||
|
end
|
||||||
|
error("Invalid position supplied to " .. (func_name or "???")..": " .. dump(pos))
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_craftitem("advtrains_luaautomation:pcnaming",{
|
minetest.register_craftitem("advtrains_luaautomation:pcnaming",{
|
||||||
|
|
Loading…
Reference in New Issue