RTE RBC 2oo2 Specific Application 0.1.0 build 53572f9
Installer packaging and site-data libraries for the RBC_GP reference RBC
Loading...
Searching...
No Matches
site Directory Reference
Directory dependency graph for site:

Detailed Description

`ab_site.railml.xml` — single source of truth for site/track-layout data

Real railML 3.3 (https://www.railml.org/schemas/3.3), IS (infrastructure) + IL (interlocking) modules in one file, sharing one ID space so IL can refersTo/ refersToSwitch straight into IS elements. Structure and attribute names verified against the real railML 3 wiki (wiki3.railml.org) and the real schema's targetNamespace this session — not invented.

Topology v2 (this session, replacing the original single 12 km open-line dataset): two stations, WEST and EAST, each with 4 tracks (W1-W4, E1-E4, 300 m each), connected by a double-track open line — UP (WEST→EAST, 4×2000 m blocks) and DOWN (EAST→WEST, 4×2000 m blocks), same corridor. WEST's throat has two switches (SW_W_A merging W1/W2 onto UP, SW_W_B splitting DOWN into W3/W4); EAST mirrors this (SW_E_A/SW_E_B). Absolute chainage (km, WEST station = 0) is carried per balise via sapi:etcsBaliseGroup/@km — see the Extensions section below. 16 segments / 14 signals / 4 switches / 16 balises / 16 routes.

This file is read independently by two generators (see their own header comments for the full rationale — neither derives from the other, both parse this file directly):

  • RBC_GP/etc/scripts/generate_ab_site_gp.py → ab_siteGP.c (raw physical infrastructure only: segments, signals, switches, balises — no routes).
  • RBC_GA/etc/scripts/generate_ab_site_ga.py → ab_siteGA.c (route composition: built from signals + segments, route IDs exchanged with IL — the only owner of route topology now).

This split is a deliberate correction from the RailML-standard model, where routes are just another interlocking asset alongside everything else: in this codebase specifically, GP owns the physical world, GA owns the interlocking-route logic that IL talks to — see the Platform_RTE workspace root CLAUDE.md's GP/GA/SA section and this session's own plan file for why.

Extensions

Three fields have no confirmed native railML attribute after this session's own research (not from lack of trying — see the caveats below) and use railML's own sanctioned per-element <extensions> mechanism, under a project-local namespace (xmlns:sapi="https://rterbc2oo2.example/schemas/sapi-ext/1" — not a real, registered railML extension, just a private one scoped to this project):

  • sapi:trackDescription on each track — vMaxKmh, gradientPermil, switchId (the segment's own switch_id back-reference, i.e. "this segment begins at this turnout").
  • sapi:switchDescription on each switchIS — defaultPosition, maxSpeedStraightKmh, maxSpeedDivergingKmh (no confirmed native IL:switchIL overlay found this session for default_position — worth re-checking against a downloaded real XSD before treating this as final, per the open caveats below).
  • sapi:routeDescription on each route — lengthM (no native IL:route length attribute confirmed) and baliseNidLrbg (Subset-026's 24-bit ETCS balise ID — genuinely outside railML's generic scope, not a gap in this session's research).
  • sapi:etcsBaliseGroup/@km (added for topology v2) — absolute chainage in kilometers (e.g. "6.050"), measured from the WEST station's own zero point. No native railML absolute-chainage attribute was confirmed (railML's own position model is relative, spotLocation/@pos = offset within a netElement) — generated into ab_site_balise_t's new chainage_m field (meters, for unit consistency with every other distance field) purely for display purposes (web_runner's balise/km markers), not read by any safety-relevant logic.

Field mapping (native vs. derived vs. extension)

C field (today's ab_site*.h) railML source Nature
segment id POSITIONAL: document order of netElement in <netElements> (1..N) derived — see "ID assignment" caveat below
segment prev_segment_id/next_segment_id netRelation/@elementA/@elementB (adjacency graph), resolved to the positional id above; first relation seen per netElement wins at a branch point derived, simplified — see caveat below
segment length_m netElement/@length native
segment v_max_kmh/gradient_permil/switch_id sapi:trackDescription extension
segment start_signal_id/end_signal_id boundary-signal lookup: a signal at pos=0/pos=length on this segment's own netElement, falling back to the adjacent segment's own boundary position if none sits locally (both placement conventions appear in this topology - see caveat below) derived
signal id POSITIONAL: document order of signalIS in <signalsIS> (1..N) derived — signalIS/@id no longer carries a parseable numeric convention (topology v2 names like SW1/HW/U1 replaced the old "S"+number scheme)
signal name signalIS's own designator (@name) native
signal segment_id/pos_m/direction spotLocation/@netElementRef/@pos/@applicationDirection native
signal type IS:signalIS/@type native
signal function/sight_distance_m IL:signalIL/@function/@sightDistance (an IL overlay on the IS signal, via refersTo) native, different module than type
switch id/name/segment_id/pos_m switchIS/@id/designator + spotLocation; id is POSITIONAL (document order), same as segments/signals native fields, positional id
switch normal_segment_id/reverse_segment_id switchIS/@continueCourse/@branchCourse, resolved to the referenced netElement's own positional segment id native reference, derived id
switch default_position/max_speed_*_kmh sapi:switchDescription extension
balise nid_lrbg sapi:etcsBaliseGroup/@nidLrbg extension
balise name/segment_id/pos_m/direction baliseGroup/@id + spotLocation native
balise chainage_m sapi:etcsBaliseGroup/@km × 1000 extension (see above)
balise route_id cross-reference: which route's sapi:routeDescription/@baliseNidLrbg names this balise derived
route id/name route/@id/@designator native
route start_signal/end_signal routeEntry/routeExit's refersTo, resolved to the referenced signal's own positional id native reference, derived id
route prev_route_id/next_route_id derived: route A's end_signal == route B's start_signal derived (no native field — confirmed absent from IL:route's child list)
route length_m sapi:routeDescription/@lengthM extension (no native field — confirmed absent; matches what ab_siteGP.h's own pre-existing doc comment already treated as "sum of segments," i.e. already conceptually derived, not a new burden)
route segment_ids[]/segment_count hasTvdSection/@ref → its track's own netElementRef → that netElement's positional segment id derived
route switch_ids[]/switch_positions[]/switch_count facingSwitchInPosition/trailingSwitchInPosition (refersToSwitch + inPosition), refersToSwitch resolved to the referenced switch's own positional id native structure, derived id. inPosition ("normal"/"reverse") maps to this project's NORMAL/REVERSE enum via the referenced switch's own continueCourse/branchCourse — handedness isn't assumed fixed
route balise_nid_lrbgs[]/balise_count sapi:routeDescription/@baliseNidLrbg extension

ID assignment and singular-field simplifications (topology v2)

The original single open-line topology used names a plain numeric-suffix parse could read directly (ne_segNN, "S"+number). Topology v2's branching, two-station layout doesn't fit that convention (ne_w1, sig_HW, sig_U1, ...), so all three independent readers (generate_ab_site_gp.py, generate_ab_site_ga.py, and RBC_Test_Env/etc/scripts/generate_site_routes_resource.py) now assign segment/signal/switch ids positionally — 1..N by document order of netElement/ signalIS/switchIS respectively. All three readers see the same document order in the same file, so they agree with no shared code or build-order coupling — the same independent-generator principle the rest of this file already relies on.

Two singular-field simplifications fall out of this topology's real branch points, both accepted deliberately rather than treated as bugs:

  • prev_segment_id/next_segment_id are singular fields, but a real branch/merge point (e.g. ne_up1 has two predecessors, ne_w1 and ne_w2, converging through SW_W_A) has more than one valid adjacency. Each reader keeps only the FIRST netRelation seen (document order) per netElement — nothing is actually lost, since the switch's own normal_segment_id/reverse_segment_id already carries the full branching truth.
  • A segment's start_signal_id/end_signal_id are also singular, but this topology has one genuine physical co-location: HW and D4 both sit at ne_down4/pos=2000 (the junction between the DOWN block-signal chain and the WEST station throat). HW, declared first in document order, wins that position; D4 still gets its own row in ab_site_signals[] (segment_id=that same segment, pos_m=2000), it just isn't referenced by any segment's own boundary-signal field. Its role as the block-chain terminus is fully captured in GA's route table instead (routes R_D3_D4 / R_D4_HW, a zero-length pseudo-route connecting the two).

Open caveats (resolve before treating this file as final / before real XSD validation)

Flagged honestly rather than glossed over — this file was authored against the real railML 3 wiki documentation and the real schema's confirmed targetNamespace, but not validated against a downloaded real XSD (attempts to fetch the raw schema file this session didn't return usable binary/XSD content via the available tools):

  1. The exact speed-restriction element/attribute shape (speeds container confirmed to exist under functionalInfrastructure; its own internal structure was not confirmed) — v_max_kmh was kept as an extension rather than guessed into a real speeds element that might be structured differently than assumed.
  2. default_position's real home (a switchIS attribute vs. an IL:switchIL overlay, mirroring the signalIS/signalIL split confirmed for signals) — kept as an extension.
  3. Gradient's real container (no dedicated gradient child was found under functionalInfrastructure in this session's research; real railML likely models this via track geometry/vertical alignment elsewhere) — kept as an extension.

None of these affect correctness of the generators reading this file (they read the sapi:* extensions either way) — they only affect how "standards-pure" the file is. Worth a follow-up pass with a real XSD validator (xmllint --schema) against the actual downloaded 3.3 schema if this ever needs to interoperate with real external railML tooling.