ILRBCSim
ADR-029 Interlocking simulator — grants/extends Movement Authority against the RBC wire protocol
Toggle main menu visibility
Loading...
Searching...
No Matches
site_data.py
Go to the documentation of this file.
1
"""site_data.py - IL sim's own tiny RailML reader.
2
3
Independently re-parses safeAPIRBC2oo2SA/etc/site/ab_site.railml.xml -
4
see TrainRBCSim/src/train/site_data.py's own header for the full "why a
5
FOURTH independent reader, not a shared library call" rationale (matches
6
the no-pipeline-coupling convention safeAPIRBC2oo2GP's/GA's own RailML
7
generators already established).
8
9
Unlike Train's own reader, this is genuinely NEW ground for IL - today's
10
il_sim.py hardcodes no route data at all (every ROUTE_ADD's own
11
start_signal/end_signal/route_len is entirely test/command-supplied, see
12
that file's own header doc). This module gives IL its own real route
13
table (id/name/start_signal/end_signal/length_m), the same shape
14
safeAPIRBC2oo2GA/etc/scripts/generate_ab_site_ga.py's own
15
ab_site_ga_route_layout_t table already carries and the SAME positional-
16
id convention it uses (route/signal ids assigned by RailML document
17
order, not parsed from the element's own @id string) - so a route id
18
this module reports lines up numerically with what GP/GA's own C code
19
means by that same id.
20
"""
21
22
import
logging
23
import
os
24
import
xml.etree.ElementTree
as
ET
25
26
_RAILML_NS =
"https://www.railml.org/schemas/3.3"
27
_SAPI_NS =
"https://safeapirbc2oo2.example/schemas/sapi-ext/1"
28
_NS = {
"r"
: _RAILML_NS,
"sapi"
: _SAPI_NS}
29
30
# ILRBCSim/src/il/ -> up 3 (il, src, ILRBCSim) -> the SAPI workspace root
31
# -> safeAPIRBC2oo2SA's own sibling checkout - same convention
32
# TrainRBCSim/src/train/site_data.py's own DEFAULT_RAILML_PATH uses.
33
_WORKSPACE_ROOT = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)),
".."
,
".."
,
".."
))
34
DEFAULT_RAILML_PATH = os.path.join(_WORKSPACE_ROOT,
"safeAPIRBC2oo2SA"
,
"etc"
,
"site"
,
"ab_site.railml.xml"
)
35
36
37
def
routes
(railml_path=None):
38
"""@return a list of {"id", "name", "start_signal", "end_signal",
39
"length_m"} dicts, one per <route>, ordered and id-numbered exactly
40
the way generate_ab_site_ga.py's own parse_railml() derives them
41
(signal/route ids by document-order position, length_m read directly
42
from each route's own sapi:routeDescription/@lengthM extension - no
43
segment-length summation needed, that field is already explicit).
44
Raises on a genuinely missing/malformed RailML file - unlike Train's
45
balise_names() (a pure log-decoration convenience), a route table
46
this sim doesn't have at all today is real, load-bearing IL data
47
(this is what Phase D's own periodic route-status broadcast iterates
48
over) - a silent empty-table fallback here would make IL announce
49
"there are zero routes," which is materially wrong, not just
50
cosmetically incomplete like a missing balise name would be."""
51
path = railml_path
or
os.environ.get(
"SAPI_RAILML_PATH"
)
or
DEFAULT_RAILML_PATH
52
tree = ET.parse(path)
53
root = tree.getroot()
54
infra = root.find(
"r:infrastructure"
, _NS)
55
fi = infra.find(
"r:functionalInfrastructure"
, _NS)
56
il = root.find(
"r:interlocking"
, _NS)
57
afi = il.find(
"r:assetsForInterlockings/r:assetsForInterlocking"
, _NS)
58
routes_el = afi.find(
"r:routes"
, _NS)
59
60
signal_list = fi.find(
"r:signalsIS"
, _NS).findall(
"r:signalIS"
, _NS)
61
sig_pos_by_xmlid = {sig.get(
"id"
): i
for
i, sig
in
enumerate(signal_list, start=1)}
62
63
result = []
64
for
i, rt
in
enumerate(routes_el.findall(
"r:route"
, _NS), start=1):
65
entry = rt.find(
"r:routeEntry"
, _NS).get(
"refersTo"
)
66
exit_ = rt.find(
"r:routeExit"
, _NS).get(
"refersTo"
)
67
rext = rt.find(
"r:extensions/sapi:routeDescription"
, _NS)
68
result.append({
69
"id"
: i,
70
"name"
: rt.get(
"designator"
, rt.get(
"id"
, f
"Route_{i}"
)),
71
"start_signal"
: sig_pos_by_xmlid[entry],
72
"end_signal"
: sig_pos_by_xmlid[exit_],
73
"length_m"
: int(rext.get(
"lengthM"
)),
74
})
75
if
not
result:
76
raise
ValueError(f
"RailML file at {path!r} parsed but yielded zero routes"
)
77
return
result
il.site_data.routes
routes(railml_path=None)
Definition
site_data.py:37
src
il
site_data.py
Generated by
1.18.0