Skip to content

CAMP running-task view P1: read-only structured task tree#128

Merged
rolker merged 5 commits into
jazzyfrom
feature/issue-127
Jun 28, 2026
Merged

CAMP running-task view P1: read-only structured task tree#128
rolker merged 5 commits into
jazzyfrom
feature/issue-127

Conversation

@rolker

@rolker rolker commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Closes #127

Summary

Adds a read-only structured running-task view to CAMP, sourced from the boat's
marine_nav_interfaces/TaskFeedback on marine/status/mission_tasks
(rolker/unh_marine_autonomy#236). This is P1 of the running-task display redesign
(umbrella #123) — it replaces the placeholder Heartbeat text-dump experience with a
real task tree, alongside the existing MissionManager widget (left in place).

What's here

  • RunningTasksModel (QAbstractItemModel) — builds a tree from the flat
    TaskInformation[] keyed on the slash-delimited id (survey_a/line_1 → child
    of survey_a; synthetic group rows for intermediate segments). Columns:
    name / type / priority / status / done. The current navigation task is rendered
    bold + highlighted.
  • RunningTasksView (QWidget) — node-injection widget (the helm_manager
    idiom, not camp_ros::ROSWidget): setNode() + updateRobotNamespace().
    The TaskFeedback subscription uses the guarded Realtime callback group
    (if (auto ctx = camp_ros::RosContext::instance()) ...) → Realtime group in
    CAMP, default group when later hosted in rqt. The ROS callback converts to Qt
    rows and marshals to the GUI thread via a queued invoke + mutex (never touches
    Qt off the executor thread). Exposes taskSelected() / setSelectedTask() for
    the P2 map glue.
  • Promoted into the Platform splitter (platform.ui) next to helm/mission;
    setNode + updateRobotNamespace wired in platform.cpp.
  • marine_nav_interfaces added to CMakeLists.txt + package.xml.

Design notes

This follows the dual-use architecture from #123: the node-agnostic core is
rqt-hostable later with no rework, and map linkage / editing (P2/P3) attach as
CAMP-only glue via the widget's signals — never baked into the core.

Testing

  • colcon build of camp clean (full + incremental), no new warnings from the
    added files.
  • Pre-push review (Deep): one must-fix (a destructor use-after-free) and two
    suggestions found and fixed before push (see the Fix review findings
    commit): explicit dtor resets the subscription first; QSignalBlocker around
    selection-restore so it doesn't re-emit taskSelected on every republish;
    current_task_ normalized to match node ids. Rebuilt clean after the fixes.
  • Custom model index/parent/rowCount consistency + rowInParent stability
    verified by a concrete tree walk during review.

Follow-ups (later phases under #123)

  • rqt wrapper (rqt_running_tasks + plugins.xml) — additive, no core rework.
  • P2 map linkage (tasks carry poses[]), P3 editing/nudge, P4 mission progress.
  • Synthetic group rows currently emit taskSelected(groupId); guard when the P2
    map glue consumes the signal.

Authored-By: Claude Code Agent
Model: Claude Opus 4.8 (1M context)

Claude Code Agent added 5 commits June 28, 2026 09:20
Read-only structured running-task tree view (node-injection widget +
QAbstractItemModel over hierarchical TaskInformation ids), P1 of camp#123.
P1 of the CAMP running-task display redesign (camp#123). A node-injection
QWidget (the helm_manager idiom, not camp_ros::ROSWidget) that subscribes to
the boat's structured marine_nav_interfaces/TaskFeedback on
marine/status/mission_tasks and renders it as a tree.

- RunningTasksModel (QAbstractItemModel): builds a tree from the flat
  TaskInformation list keyed on the slash-delimited id; columns
  name/type/priority/status/done; bold + highlight on the current task.
- RunningTasksView (QWidget): setNode() + updateRobotNamespace(); subscription
  uses the guarded Realtime callback group (Realtime in CAMP, default group in
  rqt). ROS callback converts to Qt rows and marshals to the GUI thread via a
  queued invoke + mutex (never touches Qt off the executor thread). Exposes
  taskSelected()/setSelectedTask() for the P2 map glue.
- Promoted into the Platform splitter (platform.ui) alongside helm/mission;
  wired setNode + updateRobotNamespace in platform.cpp.
- CMake + package.xml gain marine_nav_interfaces.

The placeholder MissionManager widget is left in place. Builds clean
(colcon, 3min). Map linkage, editing, and the rqt wrapper are later phases.
)

Pre-push review (Deep) findings:
- must-fix: ~RunningTasksView was =default, so pending_mutex_/pending_rows_
  (declared after subscription_) were destroyed before subscription_ under
  reverse-order destruction — a callback in flight at teardown would deref freed
  members. Explicit dtor now resets subscription_ first.
- selection restore re-emitted taskSelected() on every periodic republish
  (P2 map-glue feedback-loop risk): block signals around setCurrentIndex.
- current-task highlight could miss when the id carried stray slashes: normalize
  current_task_ the same way node fullIds are built.

Rebuilt clean (colcon incremental).
Copilot AI review requested due to automatic review settings June 28, 2026 13:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@rolker rolker merged commit 9840b89 into jazzy Jun 28, 2026
1 check failed
@rolker rolker deleted the feature/issue-127 branch June 28, 2026 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CAMP running-task view P1: read-only structured task tree

2 participants