User Tools

Site Tools


dev:core:path

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
Next revision Both sides next revision
dev:core:path [2020-04-14 12:48]
orwell created
dev:core:path [2020-06-24 12:26]
orwell more documentation, note on invalidate_ahead
Line 26: Line 26:
  
 A train is moved by advancing its index. It is important to note that the train's 'index' is always incremented, never decremented. See also "reversion" in [[dev:core:train]]. A train is moved by advancing its index. It is important to note that the train's 'index' is always incremented, never decremented. See also "reversion" in [[dev:core:train]].
 +
 +===== Distances =====
 +
 +It is important to keep in mind that the index has little to no relation to actual distances in the cartesian space. Depending on the track orientation, the distance between path items can vary from 1 to >2 nodes. The real distance of every item from path item 0 is encoded in ''train.path_dist''
 +
 +To calculate an index for a given starting index and a given distance, you can use ''advtrains.path_get_index_by_offset()''
 +
 +===== In train table =====
 +The following tables in the train table are handled by the path system:
 +<code>
 +-- path      - path positions. 'indices' are relative to this. At the moment, at.round_vector_floor_y(path[i])
 +--              is the node this item corresponds to, however, this will change in the future.
 +-- path_node - (reserved)
 +-- path_cn   - Connid of the current node that points towards path[i+1]
 +-- path_cp   - Connid of the current node that points towards path[i-1]
 +--     When the day comes on that path!=node, these will only be set if this index represents a transition between rail nodes
 +-- path_dist - The total distance of this path element from path element 0
 +-- path_dir  - The direction of this path item's transition to the next path item, which is the angle of conns[path_cn[i]].c
 +--Variables:
 +-- path_speed   - Filled by the LZB subsystem. For every path item, if set, defines the maximum velocity the train is allowed to have in the moment it passes this path item.
 +--              - If 0, the train will stop 0.1 indices before this path item (definable by LZB_ZERO_APPROACH_DIST in trainlogic.lua)
 +-- path_ext_f/b - how far path[i] is set
 +-- path_trk_f/b - how far the path extends along a track. beyond those values, paths are generated in a straight line.
 +-- path_req_f/b - how far path items were requested in the last step
 +</code>
 +
  
 ===== Path generation ===== ===== Path generation =====
  
 +The path is generated on the fly, as path items are requested.
 +
 +Every call to ''advtrains.path_get()'' (or one of the related functions) automatically generates the path as far as needed. In order to access any of the secondary path tables (such as path_speed or path_cn), you need to make sure that ''advtrains.path_get()'' was called before. However, advtrains ensures that the range from ''train.index'' to ''train.end_index'' is always existent.
 +
 +The path system deletes path items that are behind the train and no longer needed automatically.
 +
 +===== Invalidation and restoration =====
 +
 +Whenever the tracks in the world change (e.g. a switch is switched), it is required to update (say 'invalidate') the paths of trains that include the changed track. This happens by a call to ''advtrains.invalidate_all_paths(pos)''.
 +
 +//With the ''new_lzb'' branch, it is preferred to use ''advtrains.invalidate_all_paths_ahead(pos)''. See ''invalidate ahead'' below.//
 +
 +A path invalidation clears all path-related tables and variables. They remain cleared until the next call to ''train_ensure_init()'', which should be called before operating on a train, but is at least called before the next train step.
 +
 +To restore the path from save files or after a path invalidation, the following values are saved in the train (and in the save files) in every step:
 +
 +<code>
 +train.last_pos -- the world position of the path item currently at floor(train.index)
 +train.last_connid = the connid of the track connection pointing forward
 +train.last_frac = the fractional part of train.index
 +</code>
 +
 +To restore, train.last_pos becomes path item 0, train.index becomes last_frac, and path generation continues in last_connid direction. This causes an index shift, which also prevents integer overflows.
 +
 +Note that, to have an estimated rough position of a train, you can simply query ''train.last_pos''.
 +
 +A path invalidation can also occur when LZB checkpoints change, see [[dev:core:lzb]] for more info on that.
 +
 +===== Invalidate Ahead =====
 +
 +In order to prevent a complete path recalculation when a far-away rail changes, ''path_invalidate_ahead()'' was added in the ''new_lzb'' branch. This function clears path items that are **ahead of** (exclusive) the passed index, and does not cause an index shift.
 +
 +Obviously, due to the way the path restoration works, this would cause problems when the starting index is behind the train's current index. By default, when this case happens, ''path_invalidate_ahead()'' throws an error. However passing the ''ignore_when_passed = true'' parameter causes nothing to happen in this case, which is sometimes desirable and sufficient (e.g. when a switch is switched after the train has already passed it, it doesn't matter).
 +
 +''path_invalidate_ahead()'' also invalidates LZB checkpoints and re-calls approach callbacks up from the given index. Important: LZB invalidation occurs **inclusive**, so the first approach callback to be called again is the node at ''index'', although the first path item that was actually cleared was ''index + 1''. This is required for interlocking signals to work.
  
 +In the future, path_invalidate_ahead() is to be preferred over path_invalidate().
  
dev/core/path.txt · Last modified: 2023-01-11 15:13 by 56independent