braidpath op• Data kinds: any × any → table
• Call: import fullseye as fs; fs.ledger.homotopy_class_compare(traj_a, traj_b, obstacles=None, angle=0.1, jitter='auto', tol=1e-09) (to call the implementation directly, import braidpath; braidpath.homotopy_class_compare(traj_a, traj_b, obstacles=None, angle=0.1, jitter='auto', tol=1e-09); from the registry, opsdrive.get("homotopy_class_compare"))
• GPU: none (CPU reference implementation only)
Whether two path families with the same start and end points (multi-agent plans) are in the same homotopy class.
Can be deformed continuously without collision (no overlap between agents or with obstacle points) while start and end points stay fixed ⇔ the braids are equal. The braid comes from braid_from_trajectories, the comparison uses Dynnikov coordinates. Independent of the projection angle (the gate sweeps several angles).
Returns: dict same, word_a / word_b, key_a / key_b, quotient (the reduced word of a b⁻¹ —— empty means the same class; otherwise a word describing “how the windings differ”), endpoint_error (largest deviation of the start and end points), tol_limit (the upper bound of tol). Start and end points must agree within tol (default ENDPOINT_TOL = 1e-9, in coordinate units, the largest per-coordinate difference). tol is a gate that only passes / rejects without changing the answer, and is listed with its reason in the ledger of knobs with no effect. Endpoints of B that deviate within tol are moved onto A's endpoints by straight segments added before and after B, and then compared (word_b is the word of that aligned plan). The upper bound of tol is tol_limit = d / (2√2) (d = the smallest distance between strands in A's start and end configurations, obstacle points included):
each agent moves at most tol per coordinate = at most √2·tol in distance, so the distance between two agents changes by less than 2√2·tol, and the aligning segments do not collide. Moreover, the set of configurations within tol per coordinate of A's endpoints is convex and collision-free, so the class does not depend on how the endpoints are aligned —— the answer depends neither on the projection angle nor on tol. A tol above the bound is rejected, because it could call plans with different endpoints the same class. If the endpoints of different planners differ by rounding, widen tol within the bound or align the endpoints before comparing (the class is the class of deformations with fixed endpoints, so two plans with different endpoints cannot be compared).
Raises: ValueError (different number of agents, start or end points farther apart than tol, tol negative, non-finite or ≥ tol_limit, the order of the start or end points along the projection disagrees, collision).
• Sample-data catalog (download URLs / licences) — 2-D uses skimage.data (BSD/public domain) plus synthetic images; 3-D lists download URLs for real data sources (Stanford, PDS, …).
• Operator provenance and references — the sources of the research/methods this op family came from.
• The canonical algorithm (author, year) and its uses are named in the family usage guide above.
• poc_braid_homotopy_classes — py -3.11 examples/poc_braid_homotopy_classes.py
table as input)course_layout · course_occupancy · course_contains · world_build · world_camera · world_move · lidar_scan · rss_longitudinal_same
braidpath)braid_from_trajectories · braid_reduce · braid_artin_images · dynnikov_coordinates · dynnikov_act · braid_equivalent · pairwise_winding · homotopy_shortest_paths
*Provenance: braidpath.py — DRIVE operator registry. This per-op note is generated by tools/opdocs.py md (do not hand-edit).*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.