CAMP running-task view P1: read-only structured task tree#128
Merged
Conversation
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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #127
Summary
Adds a read-only structured running-task view to CAMP, sourced from the boat's
marine_nav_interfaces/TaskFeedbackonmarine/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
MissionManagerwidget (left in place).What's here
RunningTasksModel(QAbstractItemModel) — builds a tree from the flatTaskInformation[]keyed on the slash-delimitedid(survey_a/line_1→ childof
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 (thehelm_manageridiom, not
camp_ros::ROSWidget):setNode()+updateRobotNamespace().The
TaskFeedbacksubscription uses the guarded Realtime callback group(
if (auto ctx = camp_ros::RosContext::instance()) ...) → Realtime group inCAMP, 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()forthe P2 map glue.
Platformsplitter (platform.ui) next to helm/mission;setNode+updateRobotNamespacewired inplatform.cpp.marine_nav_interfacesadded toCMakeLists.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 buildofcampclean (full + incremental), no new warnings from theadded files.
suggestions found and fixed before push (see the
Fix review findingscommit): explicit dtor resets the subscription first;
QSignalBlockeraroundselection-restore so it doesn't re-emit
taskSelectedon every republish;current_task_normalized to match node ids. Rebuilt clean after the fixes.rowInParentstabilityverified by a concrete tree walk during review.
Follow-ups (later phases under #123)
rqt_running_tasks+plugins.xml) — additive, no core rework.poses[]), P3 editing/nudge, P4 mission progress.taskSelected(groupId); guard when the P2map glue consumes the signal.
Authored-By:
Claude Code AgentModel:
Claude Opus 4.8 (1M context)