Skip to content

[ISSUE]: Refactor edge action handling: stop inferring actions from node names and use topological map edge metadata #218

@ibrahimhroob

Description

@ibrahimhroob

Description

Problem Statement

The current navigation/action logic infers behaviours and actions from node naming conventions, which is fragile and incorrect.
Actions such as goal alignment, row traversal, row operation, etc., are currently derived purely from string patterns in node names (e.g. "ca", "cb", "WayPoint"), rather than from the explicit action definitions already present on topological map edges.

This affects logic spread across the following files and needs coordinated refactoring:

  • edge_action_manager2.py
  • actions_bt.py
  • localisation2.py
  • navigation2.py

Current Implementation (Issue)

In actions_bt.py, actions are hard-coded and inferred from node name tokens:

self.ROW_TRAVERSAL = "row_traversal"
self.ROW_OPERATION = "row_operation"
self.ROW_RECOVERY = "row_recovery"
self.ROW_CHANGE = "row_change"
self.GOAL_ALIGN = "goal_align"

self.GOAL_ALIGN_INDEX = ["ca"]
self.GOAL_ALIGN_GOAL = ["cb"]

self.ROW_START_INDEX = "a"
self.ROW_COLUMN_START_INDEX = "c"
self.ROW_COLUMN_START_NEXT_INDEX = "b"
self.OUTSIDE_EDGE_START_INDEX = "WayPoint"

This leads to logic such as:

  • If node name contains "ca" → trigger goal_align
  • If node starts with "WayPoint" → treat as outside edge
  • If node index matches certain letters → infer row behaviour

This approach is:

  • brittle
  • map-specific
  • hard to extend
  • semantically incorrect (node names should not encode behaviour)

Expected / Correct Behaviour

Actions must be derived from the topological map edges, not inferred from node names.

The topological map already defines explicit action metadata on each edge.
This metadata must be treated as the single source of truth.

Example (existing, correct data already available):

edges:
  - action: row_traversal
    action_type: geometry_msgs/PoseStamped
    edge_id: r13.7-ca_r13.7-cb
    fluid_navigation: true
    goal:
      target_pose:
        header:
          frame_id: $node.parent_frame
        pose: $node.pose
    node: r13.7-ca
    fail_policy: fail
    restrictions_planning: robot_short
    restrictions_runtime: obstacleFree_1

From this:

  • The action (row_traversal)
  • The goal type
  • The behavioural constraints
  • The recovery configuration

are all already explicitly defined.

The system should:

  • Read the selected edge
  • Extract edge.action
  • Drive BT selection, navigation mode, localisation mode, and recovery behaviour from that value
  • Never infer behaviour from node naming patterns

Required Refactor

1. Action Source of Truth

  • Replace all node-name-based action inference with edge metadata parsing

  • edge.action must determine:

    • Behaviour Tree branch
    • Navigation mode
    • Goal handling
    • Recovery behaviour

2. File-level Expectations

edge_action_manager2.py

  • Select and propagate the active edge
  • Expose the edge’s action, action_type, and config cleanly

actions_bt.py

  • Remove all logic tied to:

    • "ca", "cb", "WayPoint", index letters, etc.
  • Map BT actions directly from edge.action

navigation2.py

  • Trigger navigation behaviours based on edge action
  • Do not inspect node names for behaviour switching

localisation2.py

  • Ensure localisation strategy changes (if any) are driven by edge action, not node identity

Additional Investigation Required

There is a noticeable long pause / wait when:

  • Switching actions
  • Changing behaviours
  • Transitioning between BT states

This needs investigation:

  • Is the delay caused by:

    • BT reloading?
    • Action server teardown/recreation?
    • Navigation goal cancellation?
    • Blocking localisation resets?
  • Identify where the blocking occurs and reduce or eliminate unnecessary waits


Acceptance Criteria

  • No behaviour depends on node naming conventions
  • All actions are derived exclusively from topological map edge metadata
  • BT transitions are driven by edge.action
  • Behaviour switching latency is understood and reduced
  • Code paths across the four files are consistent and maintainable

Motivation

This change is critical to:

  • Support multiple maps with different naming schemes
  • Make behaviour semantics explicit and debuggable
  • Avoid hidden coupling between map naming and navigation logic
  • Enable future extension without renaming nodes

Notes for Copilot / PR Implementation

  • Assume node names are arbitrary identifiers
  • Treat edges as first-class behavioural entities
  • Prefer explicit data over inferred heuristics
  • Keep refactor incremental but remove legacy inference paths entirely

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions