Improve route programming:

- Formspec for TCBs instead of unhandy chatcommands
- Ability to advance route over the next secction without punching end
- Better visualization
- Ability to route into dead-end sections
master
orwell96 2018-10-07 22:21:49 +02:00
parent 8e70c070c1
commit 8df7bcf6b6
14 changed files with 638 additions and 237 deletions

View File

@ -11,6 +11,8 @@ end
--advtrains
DUMP_DEBUG_SAVE = false
--Constant for maximum connection value/division of the circle
AT_CMAX = 16
@ -108,9 +110,9 @@ sid=function(id) if id then return string.sub(id, -6) end end
--ONLY use this function for temporary debugging. for consistent debug prints use atprint
atdebug=function(t, ...)
-- local text=advtrains.print_concat_table({t, ...})
-- minetest.log("action", "[advtrains]"..text)
-- minetest.chat_send_all("[advtrains]"..text)
local text=advtrains.print_concat_table({t, ...})
minetest.log("action", "[advtrains]"..text)
minetest.chat_send_all("[advtrains]"..text)
end
if minetest.settings:get_bool("advtrains_enable_debugging") then
@ -320,6 +322,15 @@ advtrains.avt_save = function(remove_players_from_wagons)
end
file:write(datastr)
file:close()
if DUMP_DEBUG_SAVE then
local file, err = io.open(advtrains.fpath.."_DUMP", "w")
if err then
return
end
file:write(dump(save_tbl))
file:close()
end
end
--## MAIN LOOP ##--

View File

@ -250,7 +250,7 @@ end
local function traverser(found_tcbs, pos, conns, connid, count, brk_when_found_n)
local adj_pos, adj_connid, conn_idx, nextrail_y, next_conns = advtrains.get_adjacent_rail(pos, conns, connid, advtrains.all_tracktypes)
if not adj_pos then
atdebug("Traverser found end-of-track at",pos, connid)
--atdebug("Traverser found end-of-track at",pos, connid)
return
end
-- look whether there is a TCB here
@ -258,14 +258,14 @@ local function traverser(found_tcbs, pos, conns, connid, count, brk_when_found_n
local tcb = ildb.get_tcb(adj_pos)
if tcb then
-- done with this branch
atdebug("Traverser found tcb at",adj_pos, adj_connid)
--atdebug("Traverser found tcb at",adj_pos, adj_connid)
insert_sigd_nodouble(found_tcbs, {p=adj_pos, s=adj_connid})
return
end
end
-- recursion abort condition
if count > TRAVERSER_LIMIT then
atdebug("Traverser hit counter at",adj_pos, adj_connid)
--atdebug("Traverser hit counter at",adj_pos, adj_connid)
return true
end
-- continue traversing
@ -316,7 +316,7 @@ function ildb.sync_tcb_neighbors(pos, connid)
error("update_tcb_neighbors but node is NOK: "..minetest.pos_to_string(pos))
end
atdebug("Traversing from ",pos, connid)
--atdebug("Traversing from ",pos, connid)
local counter_hit = traverser(found_tcbs, pos, conns, connid, 0)
local ts_id
@ -328,7 +328,7 @@ function ildb.sync_tcb_neighbors(pos, connid)
for idx, sigd in pairs(found_tcbs) do
local tcbs = ildb.get_tcbs(sigd)
if not tcbs.ts_id then
atdebug("Sync: put",sigd_to_string(sigd),"into list_eoi")
--atdebug("Sync: put",sigd_to_string(sigd),"into list_eoi")
table.insert(list_eoi, sigd)
elseif not ts_id and tcbs.ts_id then
if not ildb.get_ts(tcbs.ts_id) then
@ -336,7 +336,7 @@ function ildb.sync_tcb_neighbors(pos, connid)
tcbs.ts_id = nil
table.insert(list_eoi, sigd)
else
atdebug("Sync: put",sigd_to_string(sigd),"into list_ok")
--atdebug("Sync: put",sigd_to_string(sigd),"into list_ok")
ts_id = tcbs.ts_id
table.insert(list_ok, sigd)
end

View File

@ -112,13 +112,16 @@ route = {
next = <sigd>, -- of the next (note: next) TCB on the route
locks = {<pts> = "state"} -- route locks of this route segment
}
terminal =
}
The first item in the TCB path (namely i=0) is always the start signal of this route,
so this is left out.
All subsequent entries, starting from 1, contain:
- all route locks of the segment on TS between the (i-1). and the i. TCB
- the next TCB signal describer in proceeding direction of the route.
'Terminal' once again repeats the "next" entry of the last route segment.
It is needed for distant signal aspect determination. If it is not set,
the distant signal aspect is determined as DANGER.
]]--
local function chat(pname, message)
@ -129,6 +132,10 @@ local function clear_lock(locks, pname, pts)
chat(pname, pts.." is no longer affected when this route is set.")
end
local function otherside(s)
if s==1 then return 2 else return 1 end
end
function advtrains.interlocking.clear_visu_context(context)
if not markerent[context] then return end
for key, obj in pairs(markerent[context]) do
@ -150,22 +157,51 @@ function advtrains.interlocking.visualize_route(origin, route, context, tmp_lcks
end
routemarker(context, origin.p, "rte_origin", "at_il_route_start.png", oyaw, route.name)
local c_sigd = origin
for k,v in ipairs(route) do
local sigd = v.next
local yaw = 0
local node_ok, conns, rhe = advtrains.get_rail_info_at(sigd.p, advtrains.all_tracktypes)
if node_ok then
yaw = advtrains.dir_to_angle(conns[sigd.s].c)
c_sigd = v.next
-- display route path
-- Final "next" marker can be EOI, thus undefined. This is legitimate.
if c_sigd then
local yaw = 0
local node_ok, conns, rhe = advtrains.get_rail_info_at(c_sigd.p, advtrains.all_tracktypes)
if node_ok then
yaw = advtrains.dir_to_angle(conns[c_sigd.s].c)
end
local img = "at_il_route_set.png"
if k==#route and not tmp_lcks then
img = "at_il_route_end.png"
end
routemarker(context, c_sigd.p, "rte"..k, img, yaw, route.name.." #"..k)
end
local img = "at_il_route_set.png"
if k == #route then img = "at_il_route_end.png" end
routemarker(context, sigd.p, "rte"..k, img, yaw, route.name.." #"..k)
-- display locks
for pts, state in pairs(v.locks) do
local pos = minetest.string_to_pos(pts)
routesprite(context, pos, "fix"..k..pts, "at_il_route_lock.png", "Fixed in state '"..state.."' by route "..route.name.." until segment #"..k.." is freed.")
end
end
-- The presence of tmp_lcks tells us that we are displaying during route programming.
if tmp_lcks then
-- display route end markers at appropriate places (check next TS, if it exists)
local terminal = c_sigd
if terminal then
local term_tcbs = advtrains.interlocking.db.get_tcbs(terminal)
if term_tcbs.ts_id then
local over_ts = advtrains.interlocking.db.get_ts(term_tcbs.ts_id)
for i, sigd in ipairs(over_ts.tc_breaks) do
if not vector.equals(sigd.p, terminal.p) then
local yaw = 0
local node_ok, conns, rhe = advtrains.get_rail_info_at(sigd.p, advtrains.all_tracktypes)
if node_ok then
yaw = advtrains.dir_to_angle(conns[otherside(sigd.s)].c)
end
routemarker(context, sigd.p, "rteterm"..i, "at_il_route_end.png", yaw, route.name.." Terminal "..i)
end
end
end
end
-- display locks set by player
for pts, state in pairs(tmp_lcks) do
local pos = minetest.string_to_pos(pts)
routesprite(context, pos, "fixp"..pts, "at_il_route_lock_edit.png", "Fixed in state '"..state.."' by route "..route.name.." (punch to unfix)",
@ -201,10 +237,267 @@ local function get_last_route_item(origin, route)
return route[#route].next
end
local function otherside(s)
if s==1 then return 2 else return 1 end
local function do_advance_route(pname, rp, sigd, tsname)
table.insert(rp.route, {next = sigd, locks = rp.tmp_lcks})
rp.tmp_lcks = {}
chat(pname, "Added track section '"..tsname.."' to the route (revert with /at_rp_back)")
end
local function finishrpform(pname)
local rp = player_rte_prog[pname]
if not rp then return end
local form = "size[7,6]label[0.5,0.5;Finish programming route]"
local terminal = get_last_route_item(rp.origin, rp.route)
if terminal then
local term_tcbs = advtrains.interlocking.db.get_tcbs(terminal)
if term_tcbs.signal then
form = form .. "label[0.5,1.5;Route ends at signal:]"
form = form .. "label[0.5,2 ;"..term_tcbs.signal_name.."]"
else
form = form .. "label[0.5,1.5;WARNING: Route does not end at a signal.]"
form = form .. "label[0.5,2 ;Routes should in most cases end at signals.]"
form = form .. "label[0.5,2.5;Cancel if you are unsure!]"
end
else
form = form .. "label[0.5,1.5;Route leads into]"
form = form .. "label[0.5,2 ;non-interlocked area]"
end
form = form.."field[0.8,3.5;5.2,1;name;Enter Route Name;]"
form = form.."button_exit[0.5,4.5; 5,1;save;Save Route]"
minetest.show_formspec(pname, "at_il_routepf", form)
end
local function check_advance_valid(tcbpos, rp)
-- track circuit break, try to advance route over it
local lri = get_last_route_item(rp.origin, rp.route)
if not lri then
return false, false
end
local is_endpoint = false
local this_sigd, this_ts, adv_side
if vector.equals(lri.p, tcbpos) then
-- If the player just punched the last TCB again, it's of course possible to
-- finish the route here (although it can't be advanced by here.
-- Fun fact: you can now program routes that end exactly where they begin :)
is_endpoint = true
this_sigd = lri
else
-- else, we need to check whether this TS actually borders
local start_tcbs = advtrains.interlocking.db.get_tcbs(lri)
if not start_tcbs.ts_id then
return false, false
end
this_ts = advtrains.interlocking.db.get_ts(start_tcbs.ts_id)
for _,sigd in ipairs(this_ts.tc_breaks) do
if vector.equals(sigd.p, tcbpos) then
adv_side = otherside(sigd.s)
end
end
if not adv_side then
-- this TCB is not bordering to the section
return false, false
end
this_sigd = {p=tcbpos, s=adv_side}
end
-- check whether the ts at the other end is capable of "end over"
local adv_tcbs = advtrains.interlocking.db.get_tcbs(this_sigd)
local next_tsid = adv_tcbs.ts_id
local can_over, over_ts, next_tc_bs = false, nil, nil
local cannotover_rsn = "Next section is diverging (>2 TCBs)"
if next_tsid then
-- you may not advance over EOI. While this is technically possible,
-- in practise this just enters an unnecessary extra empty route item.
over_ts = advtrains.interlocking.db.get_ts(adv_tcbs.ts_id)
next_tc_bs = over_ts.tc_breaks
can_over = #next_tc_bs <= 2
else
cannotover_rsn = "End of interlocking"
end
local over_sigd = nil
if can_over then
if next_tc_bs and #next_tc_bs == 2 then
local sdt
if vector.equals(next_tc_bs[1].p, tcbpos) then
sdt = next_tc_bs[2]
end
if vector.equals(next_tc_bs[2].p, tcbpos) then
sdt = next_tc_bs[1]
end
if not sdt then
error("Inconsistency: "..dump(next_ts))
end
-- swap TCB direction
over_sigd = {p = sdt.p, s = otherside(sdt.s) }
end
end
return is_endpoint, true, this_sigd, this_ts, can_over, over_ts, over_sigd, cannotover_rsn
end
local function show_routing_form(pname, tcbpos, message)
local rp = player_rte_prog[pname]
if not rp then return end
local is_endpoint, advance_valid, this_sigd, this_ts, can_over, over_ts, over_sigd, cannotover_rsn = check_advance_valid(tcbpos, rp)
-- at this place, advance_valid shows whether the current route can be advanced
-- over this TCB.
-- If it can:
-- Advance over (continue programming)
-- End here
-- Advance and end (only <=2 TCBs, terminal signal needs to be known)
-- if not:
-- show nothing at all
-- In all cases, Discard and Backtrack buttons needed.
local form = "size[7,9.5]label[0.5,0.5;Advance/Complete Route]"
if message then
form = form .. "label[0.5,1;"..message.."]"
end
if advance_valid and not is_endpoint then
form = form.. "label[0.5,1.8;Advance to next route section]"
form = form.."image_button[0.5,2.2; 5,1;at_il_routep_advance.png;advance;]"
form = form.. "label[0.5,3.5;-------------------------]"
else
form = form.. "label[0.5,2.3;This TCB is not suitable as]"
form = form.. "label[0.5,2.8;route continuation.]"
end
if advance_valid or is_endpoint then
form = form.. "label[0.5,3.8;Finish route HERE]"
form = form.."image_button[0.5, 4.2; 5,1;at_il_routep_end_here.png;endhere;]"
if can_over then
form = form.. "label[0.5,5.3;Finish route at end of NEXT section]"
form = form.."image_button[0.5,5.7; 5,1;at_il_routep_end_over.png;endover;]"
else
form = form.. "label[0.5,5.3;Advancing over next section is]"
form = form.. "label[0.5,5.8;impossible at this place.]"
if cannotover_rsn then
form = form.. "label[0.5,6.3;"..cannotover_rsn.."]"
end
end
end
form = form.. "label[0.5,7;-------------------------]"
if #rp.route > 0 then
form = form.."button[0.5,7.4; 5,1;retract;Step back one section]"
end
form = form.."button[0.5,8.4; 5,1;cancel;Cancel route programming]"
minetest.show_formspec(pname, "at_il_rprog_"..minetest.pos_to_string(tcbpos), form)
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
local pname = player:get_player_name()
local tcbpts = string.match(formname, "^at_il_rprog_([^_]+)$")
local tcbpos
if tcbpts then
tcbpos = minetest.string_to_pos(tcbpts)
end
if tcbpos then
-- RPROG form
local rp = player_rte_prog[pname]
if not rp then
minetest.close_formspec(pname, formname)
return
end
local is_endpoint, advance_valid, this_sigd, this_ts, can_over, over_ts, over_sigd = check_advance_valid(tcbpos, rp)
if advance_valid then
if fields.advance then
-- advance route
if not is_endpoint then
do_advance_route(pname, rp, this_sigd, this_ts.name)
end
end
if fields.endhere then
if not is_endpoint then
do_advance_route(pname, rp, this_sigd, this_ts.name)
end
finishrpform(pname)
end
if can_over and fields.endover then
if not is_endpoint then
do_advance_route(pname, rp, this_sigd, this_ts.name)
end
do_advance_route(pname, rp, over_sigd, over_ts and over_ts.name or "--EOI--")
finishrpform(pname)
end
end
if fields.retract then
if #rp.route <= 0 then
minetest.close_formspec(pname, formname)
return
end
rp.tmp_locks = rp.route[#rp.route].locks
rp.route[#rp.route] = nil
chat(pname, "Route section "..(#rp.route+1).." removed.")
end
if fields.cancel then
player_rte_prog[pname] = nil
advtrains.interlocking.clear_visu_context("prog_"..pname)
chat(pname, "Route discarded.")
minetest.close_formspec(pname, formname)
return
end
advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname, rp.tmp_lcks, pname)
minetest.close_formspec(pname, formname)
return
end
if formname == "at_il_routepf" then
if not fields.save or not fields.name then return end
if fields.name == "" then
-- show form again
finishrpform(pname)
return
end
local rp = player_rte_prog[pname]
if rp then
if #rp.route <= 0 then
chat(pname, "Cannot program route without a target")
return
end
local tcbs = advtrains.interlocking.db.get_tcbs(rp.origin)
if not tcbs then
chat(pname, "The origin TCB has become unknown during programming. Try again.")
return
end
local terminal = get_last_route_item(rp.origin, rp.route)
rp.route.terminal = terminal
rp.route.name = fields.name
table.insert(tcbs.routes, rp.route)
advtrains.interlocking.clear_visu_context("prog_"..pname)
player_rte_prog[pname] = nil
chat(pname, "Successfully programmed route.")
return
end
end
end)
-- Central route programming punch callback
minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
local pname = player:get_player_name()
@ -224,38 +517,12 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
end
local tcbpos = minetest.string_to_pos(tcbpts)
-- track circuit break, try to advance route over it
local lri = get_last_route_item(rp.origin, rp.route)
if vector.equals(lri.p, tcbpos) then
chat(pname, "You cannot continue the route to where you came from!")
return
end
-- show formspec
local start_tcbs = advtrains.interlocking.db.get_tcbs(lri)
if not start_tcbs.ts_id then
chat(pname, "The previous TCB was End of Interlocking. Please complete route programming using '/at_rp_set <name>'")
return
end
show_routing_form(pname, tcbpos)
local ts = advtrains.interlocking.db.get_ts(start_tcbs.ts_id)
if not ts then atwarn("Internal error, ts inexistant for id!") return end
local found = nil
for _,sigd in ipairs(ts.tc_breaks) do
if vector.equals(sigd.p, tcbpos) then
found = otherside(sigd.s)
end
end
if not found then
chat(pname, "Previous and this TCB belong to different track sections!")
return
end
-- TODO check the path: are all route turnouts locked to the right position?
-- everything worked, just add the other side to the list
table.insert(rp.route, {next = {p = tcbpos, s = found}, locks = rp.tmp_lcks})
rp.tmp_lcks = {}
chat(pname, "Added track section '"..ts.name.."' to the route (revert with /at_rp_back)")
advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname, rp.tmp_lcks, pname)
return
end
if advtrains.is_passive(pos) then
@ -274,90 +541,6 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
end
end)
minetest.register_chatcommand("at_rp_set",
{
params = "<name>", -- Short parameter description
description = "Completes route programming procedure", -- Full description
privs = {interlocking = true},
func = function(pname, param)
return advtrains.pcall(function()
if param=="" then
return false, "Missing name parameter!"
end
local rp = player_rte_prog[pname]
if rp then
if #rp.route <= 0 then
return false, "Cannot program route without a target"
end
rp.route.name = param
local tcbs = advtrains.interlocking.db.get_tcbs(rp.origin)
if not tcbs then
return false, "The origin TCB of this route doesn't exist!"
end
table.insert(tcbs.routes, rp.route)
advtrains.interlocking.clear_visu_context("prog_"..pname)
player_rte_prog[pname] = nil
return true, "Successfully programmed route"
end
return false, "You are not programming a route!"
end)
end,
})
minetest.register_chatcommand("at_rp_back",
{
params = "", -- Short parameter description
description = "Remove last route segment", -- Full description
privs = {interlocking = true},
func = function(pname, param)
return advtrains.pcall(function()
local rp = player_rte_prog[pname]
if rp then
if #rp.route <= 0 then
return false, "Cannot backtrack when there are no route elements"
end
rp.tmp_locks = rp.route[#rp.route].locks
rp.route[#rp.route] = nil
advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname)
return true, "Route section "..(#rp.route+1).." removed."
end
return false, "You are not programming a route!"
end)
end,
})
minetest.register_chatcommand("at_rp_mark",
{
params = "", -- Short parameter description
description = "Re-set route programming markers", -- Full description
privs = {interlocking = true},
func = function(pname, param)
return advtrains.pcall(function()
local rp = player_rte_prog[pname]
if rp then
advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname)
return true, "Redrawn route markers"
end
return false, "You are not programming a route!"
end)
end,
})
minetest.register_chatcommand("at_rp_discard",
{
params = "", -- Short parameter description
description = "Discards the currently programmed route", -- Full description
privs = {interlocking = true},
func = function(pname, param)
return advtrains.pcall(function()
player_rte_prog[pname] = nil
advtrains.interlocking.clear_visu_context("prog_"..pname)
return true, "Route discarded"
end)
end,
})
--TODO on route setting
-- routes should end at signals. complete route setting by punching a signal, and command as exceptional route completion

View File

@ -163,7 +163,7 @@ function ilrs.free_route_locks_indiv(pts, ts, nocallbacks)
local i = 1
while i <= #e do
if e[i].by == ts then
atdebug("free_route_locks_indiv",pts,"clearing entry",e[i].by,e[i].rsn)
--atdebug("free_route_locks_indiv",pts,"clearing entry",e[i].by,e[i].rsn)
table.remove(e,i)
else
i = i + 1
@ -244,7 +244,7 @@ function ilrs.update_route(sigd, tcbs, newrte, cancel)
tcbs.aspect = nil
if (newrte and tcbs.routeset and tcbs.routeset ~= newrte) or cancel then
if tcbs.route_committed then
atdebug("Cancelling:",tcbs.routeset)
--atdebug("Cancelling:",tcbs.routeset)
advtrains.interlocking.route.cancel_route_from(sigd)
end
tcbs.route_committed = nil
@ -253,24 +253,24 @@ function ilrs.update_route(sigd, tcbs, newrte, cancel)
end
if newrte or tcbs.routeset then
if newrte then tcbs.routeset = newrte end
atdebug("Setting:",tcbs.routeset)
--atdebug("Setting:",tcbs.routeset)
local succ, rsn, cbts, cblk = ilrs.set_route(sigd, tcbs.routes[tcbs.routeset])
if not succ then
tcbs.route_rsn = rsn
atdebug("Routesetting failed:",rsn)
--atdebug("Routesetting failed:",rsn)
-- add cbts or cblk to callback table
if cbts then
atdebug("cbts =",cbts)
--atdebug("cbts =",cbts)
if not ilrs.rte_callbacks.ts[cbts] then ilrs.rte_callbacks.ts[cbts]={} end
advtrains.insert_once(ilrs.rte_callbacks.ts[cbts], sigd, sigd_equal)
end
if cblk then
atdebug("cblk =",cblk)
--atdebug("cblk =",cblk)
if not ilrs.rte_callbacks.lck[cblk] then ilrs.rte_callbacks.lck[cblk]={} end
advtrains.insert_once(ilrs.rte_callbacks.lck[cblk], sigd, sigd_equal)
end
else
atdebug("Committed Route:",tcbs.routeset)
--atdebug("Committed Route:",tcbs.routeset)
tcbs.route_committed = true
tcbs.route_rsn = false
tcbs.aspect = asp_generic_free
@ -283,12 +283,12 @@ end
-- sys can be one of "ts" and "lck"
-- key is then ts_id or pts respectively
function ilrs.update_waiting(sys, key)
atdebug("update_waiting:",sys,".",key)
--atdebug("update_waiting:",sys,".",key)
local t = ilrs.rte_callbacks[sys][key]
ilrs.rte_callbacks[sys][key] = nil
if t then
for _,sigd in ipairs(t) do
atdebug("Updating", sigd)
--atdebug("Updating", sigd)
-- While these are run, the table we cleared before may be populated again, which is in our interest.
-- (that's the reason we needed to copy it)
local tcbs = ildb.get_tcbs(sigd)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 B

After

Width:  |  Height:  |  Size: 534 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 514 B

After

Width:  |  Height:  |  Size: 533 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

View File

@ -164,7 +164,7 @@ advtrains.te_register_on_create(function(id, train)
elseif ts_id==nil then
atwarn("Train",id,": Unable to determine whether to block a track section!")
else
atdebug("Train",id,": Outside of interlocked area!")
--atdebug("Train",id,": Outside of interlocked area!")
end
end)

View File

@ -443,33 +443,47 @@ of the route. Now:
<ul class="itemize1">
<li class="itemize">Put any turnouts you need to lock in the correct position (e.g. by right-clicking them). This includes flank protection.
</li>
<li class="itemize">Punch them. This makes a marker saying &#8220;Route Lock Editing&#8221; appear.
<li class="itemize">Punch them. This makes a marker with a blue lock symbol appear.
</li>
<li class="itemize">If you punch a turnout again, or punch the marker, you can remove the lock again.
</li>
<li class="itemize">When you&#8217;ve locked all turnouts in the current section, go to and punch the TCB that is the border to the next track
section the train proceeds into.</li></ul>
<!--l. 364--><p class="noindent" >Once you&#8217;ve done this, the lock markers change to &#8220;Route Lock&#8221;, telling they can&#8217;t be changed anymore. Repeat the above procedure until
you have punched the final TCB, at which the route should end. As mentioned before, there should be a signal at this place,
however this is not enforced. Now, run the chat command <span
class="ectt-1000">/at_rp_set &#x003C;name of route&#x003E; </span>to complete programming the
route.
<!--l. 371--><p class="noindent" >A few hints:
<!--l. 364--><p class="noindent" >Depending on the situation, you are now offered some possibilities to proceed:
<ul class="itemize1">
<li class="itemize">Click the &#8220;Advance to next section&#8221; button if your route consists of more sections with turnouts to lock, and you need to
continue programming. Follow the above steps to set locks for the next section.</li></ul>
<!--l. 371--><p class="noindent" >Once you&#8217;ve clicked the &#8220;Advance&#8221; button, the lock markers change to a red lock symbol, telling they can&#8217;t be changed anymore. Repeat
the above procedure until you are ready to complete the programming procedure:
<ul class="itemize1">
<li class="itemize">Click the &#8220;Finish route HERE&#8221; button when you&#8217;ve set up the locks for the last track section of the route and punched the
final TCB (the one with the next signal). You will be asked for a route name and your route will be saved.
</li>
<li class="itemize">The &#8220;Finish route at end of NEXT section&#8221; button (third button) is an useful quickhand to make the route proceed one
more section. Using this button is equivalent to first clicking the &#8220;Advance&#8221; button, then flying to the end of the next track
section and finishing the route there. You can not (officially) set turnout locks in the final section using this method.</li></ul>
<!--l. 387--><p class="noindent" >A few hints:
<ul class="itemize1">
<li class="itemize">If one turnout should be locked by more than one section, set the lock only in the <span
class="ectt-1000">last </span>of those sections. Locking the same
turnout in multiple sections of a single route results in undefined behavior!
</li>
<li class="itemize">If you accidentally punched a TCB, you can run <span
class="ectt-1000">/at_rp_back </span>to undo this and return to the previous section. Due to a
bug, you have to re-set all locks of this section.
<li class="itemize">If you accidentally advanced the route wrongly, you can use the &#8220;Step back one section&#8221; button to undo this.
</li>
<li class="itemize">If you want to stop programming the entire route without saving it, run <span
class="ectt-1000">/at_rp_discard</span></li></ul>
<!--l. 384--><p class="noindent" >
<li class="itemize">If you want to stop programming the entire route without saving it, use the &#8220;Cancel route programming&#8221; button.
</li>
<li class="itemize">The third button is especially useful for programming simple block sections on a main running line, since you can stay at
the starting signal (punch starting TCB and select third button).
</li>
<li class="itemize">If a route should end in a dead end, you MUST use the &#8220;Finish in NEXT section&#8221; button, because there is no final TCB
that you could punch.
</li>
<li class="itemize">The third button does NOT work on sections with more than 2 exits, because the system won&#8217;t be able to determine the
final TCB of the route then.</li></ul>
<!--l. 408--><p class="noindent" >
<a
id="x1-47r4"></a>
<!--l. 384--><p class="noindent" ><span
<!--l. 408--><p class="noindent" ><span
class="ecsx-1200">4</span> <span
class="ecsx-1200">Interlocking</span>
<span
@ -478,15 +492,15 @@ class="ecsx-1200">system</span>
class="ecsx-1200">operation</span>
<a
id="Q1-1-0"></a>
<!--l. 386--><p class="noindent" >Setting up the interlocking for a portion of a railway network requires some time, experience and planning, but once done, there&#8217;s not
<!--l. 410--><p class="noindent" >Setting up the interlocking for a portion of a railway network requires some time, experience and planning, but once done, there&#8217;s not
much to do anymore to make trains run on your, now safer, railway. This section covers some useful practices to route trains across your
network.
<!--l. 391--><p class="noindent" >At the moment, routes can only be set by clicking the signal or via LuaATC, except if you use automatic working. It is planned to control
<!--l. 415--><p class="noindent" >At the moment, routes can only be set by clicking the signal or via LuaATC, except if you use automatic working. It is planned to control
this via the onboard computer and via a &#8220;signal box&#8221; view based on the currently broken itrainmap.
<!--l. 396--><p class="noindent" >
<!--l. 420--><p class="noindent" >
<a
id="x1-48r1"></a>
<!--l. 396--><p class="noindent" ><span
<!--l. 420--><p class="noindent" ><span
class="ecsx-1200">4.1</span> <span
class="ecsx-1200">Simple</span>
<span
@ -499,44 +513,44 @@ class="ecsx-1200">and</span>
class="ecsx-1200">cancelling</span>
<a
id="Q1-1-0"></a>
<!--l. 398--><p class="noindent" >To set a route, simply right-click the signal, select a route and click &#8220;set route&#8221;. If there are no conflicts, the signal turns green and the
<!--l. 422--><p class="noindent" >To set a route, simply right-click the signal, select a route and click &#8220;set route&#8221;. If there are no conflicts, the signal turns green and the
train is allowed to proceed.
<!--l. 402--><p class="noindent" >It may be possible that the route can not be set, because one or more other routes conflict with the current one, or a section is blocked. In
<!--l. 426--><p class="noindent" >It may be possible that the route can not be set, because one or more other routes conflict with the current one, or a section is blocked. In
this case, the signal stays red, and the conflicting item is shown in the formspec. As soon as the conflict is resolved (by cancellation
or release of the conflicting route, or the section becoming free), the requested route will be set and the signal turns
green.
<!--l. 409--><p class="noindent" >If a route is either requested or set, it can be cancelled from the signalling formspec. This means that all turnouts and sections are
<!--l. 433--><p class="noindent" >If a route is either requested or set, it can be cancelled from the signalling formspec. This means that all turnouts and sections are
released, and the signal reverts back to red. This of course only works when the train has not passed the signal yet. There is no
mechanism for Approach Locking.
<!--l. 415--><p class="noindent" >
<!--l. 439--><p class="noindent" >
<a
id="x1-49r2"></a>
<!--l. 415--><p class="noindent" ><span
<!--l. 439--><p class="noindent" ><span
class="ecsx-1200">4.2</span> <span
class="ecsx-1200">Automatic</span>
<span
class="ecsx-1200">Working</span>
<a
id="Q1-1-0"></a>
<!--l. 417--><p class="noindent" >Block signals on main running lines usually only have a single route to set, the one proceeding along the main line. Their purpose is only
<!--l. 441--><p class="noindent" >Block signals on main running lines usually only have a single route to set, the one proceeding along the main line. Their purpose is only
to show whether there are trains in the next section. So, it would be convenient if this only route would set itself again after a train
passed.
<!--l. 423--><p class="noindent" >This is what Automatic Working is for. Set a route, click &#8220;Enable Automatic Working&#8221;, and as soon as a train passes, the route is
<!--l. 447--><p class="noindent" >This is what Automatic Working is for. Set a route, click &#8220;Enable Automatic Working&#8221;, and as soon as a train passes, the route is
automatically re-set.
<!--l. 427--><p class="noindent" >This function is nearly identical to SimSig automatic signals. It can also be useful on a line with high traffic, when there&#8217;s a
<!--l. 451--><p class="noindent" >This function is nearly identical to SimSig automatic signals. It can also be useful on a line with high traffic, when there&#8217;s a
low-frequented access to a siding. You&#8217;d enable automatic working for the main route and cancel it only when you need a train to go into
the siding.
<!--l. 432--><p class="noindent" >
<!--l. 456--><p class="noindent" >
<a
id="x1-50r5"></a>
<!--l. 432--><p class="noindent" ><span
<!--l. 456--><p class="noindent" ><span
class="ecsx-1200">5</span> <span
class="ecsx-1200">Final</span>
<span
class="ecsx-1200">notes</span>
<a
id="Q1-1-0"></a>
<!--l. 434--><p class="noindent" >The interlocking system is mainly finished, though there are still some plans and ideas. They include:
<!--l. 458--><p class="noindent" >The interlocking system is mainly finished, though there are still some plans and ideas. They include:
<ul class="itemize1">
<li class="itemize">Setting routes from inside a train (via onboard computer)
</li>
@ -547,11 +561,11 @@ class="ecsx-1200">notes</span>
<li class="itemize">Distant signals
</li>
<li class="itemize">On-Train head-up display for oncoming signals (they have something like this in Czech Republic, I forgot how it&#8217;s called.)</li></ul>
<!--l. 444--><p class="noindent" >Apart from this, there&#8217;s the large oncoming project of a new timetable-based train automation system, but this will take some time to
<!--l. 468--><p class="noindent" >Apart from this, there&#8217;s the large oncoming project of a new timetable-based train automation system, but this will take some time to
evolve and is out of the scope of this document.
<!--l. 448--><p class="noindent" >If you have any suggestions, corrections, improvements, criticism or cute kittens and stuff, you can always contact me by various means
<!--l. 472--><p class="noindent" >If you have any suggestions, corrections, improvements, criticism or cute kittens and stuff, you can always contact me by various means
(Forum PM, E-Mail (orwell@bleipb.de), Linuxworks server chat a.s.o.). Have fun!
<!--l. 453--><p class="noindent" >- orwell
<!--l. 477--><p class="noindent" >- orwell
</body></html>

View File

@ -933,15 +933,7 @@ Put any turnouts you need to lock in the correct position (e.g.
\begin_layout Itemize
Punch them.
This makes a marker saying
\begin_inset Quotes eld
\end_inset
Route Lock Editing
\begin_inset Quotes erd
\end_inset
appear.
This makes a marker with a blue lock symbol appear.
\end_layout
\begin_layout Itemize
@ -956,24 +948,75 @@ When you've locked all turnouts in the current section, go to and punch
\end_layout
\begin_layout Standard
Once you've done this, the lock markers change to
Depending on the situation, you are now offered some possibilities to proceed:
\end_layout
\begin_layout Itemize
Click the
\begin_inset Quotes eld
\end_inset
Route Lock
Advance to next section
\begin_inset Quotes erd
\end_inset
, telling they can't be changed anymore.
Repeat the above procedure until you have punched the final TCB, at which
the route should end.
As mentioned before, there should be a signal at this place, however this
is not enforced.
Now, run the chat command
\family typewriter
/at_rp_set <name of route>
\family default
to complete programming the route.
button if your route consists of more sections with turnouts to lock, and
you need to continue programming.
Follow the above steps to set locks for the next section.
\end_layout
\begin_layout Standard
Once you've clicked the
\begin_inset Quotes eld
\end_inset
Advance
\begin_inset Quotes erd
\end_inset
button, the lock markers change to a red lock symbol, telling they can't
be changed anymore.
Repeat the above procedure until you are ready to complete the programming
procedure:
\end_layout
\begin_layout Itemize
Click the
\begin_inset Quotes eld
\end_inset
Finish route HERE
\begin_inset Quotes erd
\end_inset
button when you've set up the locks for the last track section of the route
and punched the final TCB (the one with the next signal).
You will be asked for a route name and your route will be saved.
\end_layout
\begin_layout Itemize
The
\begin_inset Quotes eld
\end_inset
Finish route at end of NEXT section
\begin_inset Quotes erd
\end_inset
button (third button) is an useful quickhand to make the route proceed
one more section.
Using this button is equivalent to first clicking the
\begin_inset Quotes eld
\end_inset
Advance
\begin_inset Quotes erd
\end_inset
button, then flying to the end of the next track section and finishing
the route there.
You can not (officially) set turnout locks in the final section using this
method.
\end_layout
\begin_layout Standard
@ -994,19 +1037,51 @@ last
\end_layout
\begin_layout Itemize
If you accidentally punched a TCB, you can run
\family typewriter
/at_rp_back
\family default
to undo this and return to the previous section.
Due to a bug, you have to re-set all locks of this section.
If you accidentally advanced the route wrongly, you can use the
\begin_inset Quotes eld
\end_inset
Step back one section
\begin_inset Quotes erd
\end_inset
button to undo this.
\end_layout
\begin_layout Itemize
If you want to stop programming the entire route without saving it, run
\family typewriter
/at_rp_discard
If you want to stop programming the entire route without saving it, use
the
\begin_inset Quotes eld
\end_inset
Cancel route programming
\begin_inset Quotes erd
\end_inset
button.
\end_layout
\begin_layout Itemize
The third button is especially useful for programming simple block sections
on a main running line, since you can stay at the starting signal (punch
starting TCB and select third button).
\end_layout
\begin_layout Itemize
If a route should end in a dead end, you MUST use the
\begin_inset Quotes eld
\end_inset
Finish in NEXT section
\begin_inset Quotes erd
\end_inset
button, because there is no final TCB that you could punch.
\end_layout
\begin_layout Itemize
The third button does NOT work on sections with more than 2 exits, because
the system won't be able to determine the final TCB of the route then.
\end_layout
\begin_layout Section

View File

@ -933,15 +933,7 @@ Put any turnouts you need to lock in the correct position (e.g.
\begin_layout Itemize
Punch them.
This makes a marker saying
\begin_inset Quotes eld
\end_inset
Route Lock Editing
\begin_inset Quotes erd
\end_inset
appear.
This makes a marker with a blue lock symbol appear.
\end_layout
\begin_layout Itemize
@ -956,24 +948,75 @@ When you've locked all turnouts in the current section, go to and punch
\end_layout
\begin_layout Standard
Once you've done this, the lock markers change to
Depending on the situation, you are now offered some possibilities to proceed:
\end_layout
\begin_layout Itemize
Click the
\begin_inset Quotes eld
\end_inset
Route Lock
Advance to next section
\begin_inset Quotes erd
\end_inset
, telling they can't be changed anymore.
Repeat the above procedure until you have punched the final TCB, at which
the route should end.
As mentioned before, there should be a signal at this place, however this
is not enforced.
Now, run the chat command
\family typewriter
/at_rp_set <name of route>
\family default
to complete programming the route.
button if your route consists of more sections with turnouts to lock, and
you need to continue programming.
Follow the above steps to set locks for the next section.
\end_layout
\begin_layout Standard
Once you've clicked the
\begin_inset Quotes eld
\end_inset
Advance
\begin_inset Quotes erd
\end_inset
button, the lock markers change to a red lock symbol, telling they can't
be changed anymore.
Repeat the above procedure until you are ready to complete the programming
procedure:
\end_layout
\begin_layout Itemize
Click the
\begin_inset Quotes eld
\end_inset
Finish route HERE
\begin_inset Quotes erd
\end_inset
button when you've set up the locks for the last track section of the route
and punched the final TCB (the one with the next signal).
You will be asked for a route name and your route will be saved.
\end_layout
\begin_layout Itemize
The
\begin_inset Quotes eld
\end_inset
Finish route at end of NEXT section
\begin_inset Quotes erd
\end_inset
button (third button) is an useful quickhand to make the route proceed
one more section.
Using this button is equivalent to first clicking the
\begin_inset Quotes eld
\end_inset
Advance
\begin_inset Quotes erd
\end_inset
button, then flying to the end of the next track section and finishing
the route there.
You can not (officially) set turnout locks in the final section using this
method.
\end_layout
\begin_layout Standard
@ -994,19 +1037,46 @@ last
\end_layout
\begin_layout Itemize
If you accidentally punched a TCB, you can run
\family typewriter
/at_rp_back
\family default
to undo this and return to the previous section.
Due to a bug, you have to re-set all locks of this section.
If you accidentally advanced the route wrongly, you can use the
\begin_inset Quotes eld
\end_inset
Step back one section
\begin_inset Quotes erd
\end_inset
button to undo this.
\end_layout
\begin_layout Itemize
If you want to stop programming the entire route without saving it, run
\family typewriter
/at_rp_discard
If you want to stop programming the entire route without saving it, use
the
\begin_inset Quotes eld
\end_inset
Cancel route programming
\begin_inset Quotes erd
\end_inset
button.
\end_layout
\begin_layout Itemize
The third button is especially useful for programming simple block sections
on a main running line, since you can stay at the starting signal (punch
starting TCB and select third button).
\end_layout
\begin_layout Itemize
If a route should end in a dead end, you MUST use the
\begin_inset Quotes eld
\end_inset
Finish in NEXT section
\begin_inset Quotes erd
\end_inset
button, because there is no final TCB that you could punch.
\end_layout
\begin_layout Section
@ -1105,5 +1175,53 @@ d access to a siding.
you need a train to go into the siding.
\end_layout
\begin_layout Section
Final notes
\end_layout
\begin_layout Standard
The interlocking system is mainly finished, though there are still some
plans and ideas.
They include:
\end_layout
\begin_layout Itemize
Setting routes from inside a train (via onboard computer)
\end_layout
\begin_layout Itemize
Signalbox panels, as revival of itrainmap
\end_layout
\begin_layout Itemize
Individual signal aspects for routes
\end_layout
\begin_layout Itemize
Distant signals
\end_layout
\begin_layout Itemize
On-Train head-up display for oncoming signals (they have something like
this in Czech Republic, I forgot how it's called.)
\end_layout
\begin_layout Standard
Apart from this, there's the large oncoming project of a new timetable-based
train automation system, but this will take some time to evolve and is
out of the scope of this document.
\end_layout
\begin_layout Standard
If you have any suggestions, corrections, improvements, criticism or cute
kittens and stuff, you can always contact me by various means (Forum PM,
E-Mail (orwell@bleipb.de), Linuxworks server chat a.s.o.).
Have fun!
\end_layout
\begin_layout Standard
- orwell
\end_layout
\end_body
\end_document