Skip to content

Traversability

Which ways the robot may drive on, from config/traversability.yaml. See Traversability rules for the file format.

Decide from OSM tags which ways the robot may drive on.

Turns a way's tags into drive here / never drive here / drive here reluctantly, from the operator-edited rule file config/traversability.yaml.

The rules are used through :class:TraversabilityRules by:

  • :func:~map_data.annotations.load_mapdata_with_annotations drops the non-traversable ways from the map at load time, so the route planner, the intersection rings and the osm_cloud cost cloud all describe the same network;
  • :class:~map_data.pathsolver.graph_planner.GraphPlanner filters them again (for callers that pass a raw map) and adds a rule's optional cost to the highway/surface cost of :mod:map_data.pathsolver.way_cost when it weighs the way's edges, so a "possible but unpleasant" way is taken only when the alternative is much longer;
  • the route_planner and osm_cloud nodes and the map_data_plan CLI pass the file the operator picked.

The file format is documented in config/traversability.yaml itself and in docs/planning.md. This module imports nothing from ROS.

TraversabilityRules dataclass

An ordered list of :class:Rule plus the verdict for unmatched ways.

Build one with :meth:from_file, :meth:from_dict or :func:load_traversability; an instance with no rules is the "everything is traversable at cost 0" no-op, which is what --no-traversability passes.

evaluate(tags)

Verdict for a way's tags; the first matching rule wins.

Parameters:

Name Type Description Default
tags mapping or None

The way's OSM tags. None and {} match no rule and take the file's default.

required

Returns:

Type Description
Verdict

extend(exclude_highway)

Copy of these rules that never traverses the exclude_highway values.

They become one deny rule in front of the others, so no allow rule in the file overrides them. Empty exclude_highway returns self.

extra_cost(way)

The matching rule's cost for way (0 when none asks for one).

This is an extra on top of the highway/surface cost the planners take from config/planner_defaults.yaml (:func:~map_data.pathsolver.way_cost.way_cost), for tags those tables know nothing about.

from_dict(data, source='') classmethod

Build the rules from the parsed YAML mapping.

Parameters:

Name Type Description Default
data mapping or None

{"default": {...}, "rules": [...]}; None or {} yields the no-op rules.

required
source str

File the mapping came from, kept in :attr:source for logs.

''

Raises:

Type Description
TraversabilityError

On unknown keys, a non-boolean traversable, a negative cost or a malformed match.

from_file(path) classmethod

Read and validate a YAML rule file.

is_traversable(way)

Return True when the robot may drive on way.

Verdict dataclass

What the rules say about one way.

Attributes:

Name Type Description
traversable bool

False removes the way from the map and from the graph.

cost float

Extra cost of driving here, as a fraction of the way's length, added to the highway/surface cost from planner_defaults.yaml: the graph planner weighs an edge (1 + way cost + cost) * length.

reason str

The matching rule's reason (:data:DEFAULT_REASON when no rule matched), for logs and route explanations.

TraversabilityError

Bases: ValueError

A traversability rule file is malformed.

load_traversability(path=None)

Rules from path, the package default file, or a ready-made rule set.

Parameters:

Name Type Description Default
path TraversabilityRules or str or Path or None

A :class:TraversabilityRules is returned unchanged (so every caller can accept "rules or a path"); None and "" load config/traversability.yaml from the installed package; anything else is a path to a rule file.

None

Returns:

Type Description
TraversabilityRules

Raises:

Type Description
TraversabilityError

If a rule file is given and is missing or malformed. A missing package default is not an error: it yields the no-op rules.

resolve_traversability_path(path=None)

The rule file a path of None/"" (the package default) resolves to.

Returns None when the file does not exist, which is how the nodes tell "no file to watch for changes" from a real path.