Skip to content

Pre-comp dev merge#36

Open
osu-uwrt-bot2 wants to merge 23 commits into
masterfrom
dev
Open

Pre-comp dev merge#36
osu-uwrt-bot2 wants to merge 23 commits into
masterfrom
dev

Conversation

@osu-uwrt-bot2

@osu-uwrt-bot2 osu-uwrt-bot2 commented Jul 3, 2026

Copy link
Copy Markdown

Summary by CodeRabbit

  • New Features
    • Added Rosbag Recorder and generic Service-call RViz panels.
    • Mapping panel now includes Reset Mapping and Capture Image controls.
    • Electrical panel now provides Pinger frequency/enable controls (replacing depressurization controls).
    • Control/Mission panels now publish/consume autonomy tree stack updates to drive related UI behavior.
  • Bug Fixes
    • Interactive setpoint marker visibility now respects autonomy activity.
    • Diagnostics handling is safer and avoids out-of-bounds parsing.
    • Array parameter edits now reliably track and apply per-element changes.
    • Ghost marker TF/pose updates are corrected.
  • Style
    • Improved high-DPI overlay scaling and refreshed saved RViz/visualization layouts and marker assets.

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR updates RViz visualization and marker assets, adds TreeStack-based autonomy handling, mapping controls, ghost TF publication, DPI-aware overlays, array-parameter tracking, pinger controls, and new rosbag and service panels.

Changes

RViz GUI and control panel changes

Layer / File(s) Summary
RViz scene and marker configuration
riptide_rviz/control_config_talos.rviz, riptide_rviz/riptide_rviz/config/markers.yaml, riptide_rviz/riptide_rviz/plugins_description.xml
Updates RViz displays, TF frames, mapping and vision topics, marker meshes, camera/window state, and registers the new panels.
Autonomy and mission TreeStack handling
riptide_rviz/riptide_rviz/include/riptide_rviz/ControlPanel.hpp, riptide_rviz/riptide_rviz/src/ControlPanel.cpp, riptide_rviz/riptide_rviz/include/riptide_rviz/MissionPanel.hpp, riptide_rviz/riptide_rviz/src/MissionPanel.cpp
Controls the interactive setpoint marker from TreeStack state and publishes an empty stack after task completion; diagnostic parsing validates message contents.
Mapping services and UI
riptide_rviz/riptide_rviz/include/riptide_rviz/MappingPanel.hpp, riptide_rviz/riptide_rviz/src/MappingPanel.cpp, riptide_rviz/riptide_rviz/src/MappingPanel.ui
Adds mapping reset and image-capture Trigger services, connects controls, and reorganizes mapping and calibration widgets.
Ghost TF broadcasting
riptide_rviz/riptide_rviz/python/MarkerPublisher.py
Loads a base-link offset, adjusts ghost poses, and broadcasts ghost/base_link and ghost/origin.
Overlay and parameter handling
riptide_rviz/riptide_rviz/src/OverlayDisplay.cpp, riptide_rviz/riptide_rviz/src/ParamPanel.cpp
Adds DPI-scaled overlay rendering and baseline-based array parameter change detection.
Electrical pinger controls
riptide_rviz/riptide_rviz/include/riptide_rviz/ElectricalPanel.hpp, riptide_rviz/riptide_rviz/src/ElectricalPanel.cpp, riptide_rviz/riptide_rviz/src/ElectricalPanel.ui
Replaces depressurization action handling with pinger frequency, enable, feedback, timer, and UI controls.
Rosbag recording panel
riptide_rviz/riptide_rviz/include/riptide_rviz/RosbagPanel.hpp, riptide_rviz/riptide_rviz/src/RosbagPanel.cpp, riptide_rviz/riptide_rviz/src/RosbagPanel.ui, riptide_rviz/riptide_rviz/config/rosbag_presets.yaml
Adds preset-driven topic selection and ros2 bag record process management through a new RViz panel.
Generic service caller panel
riptide_rviz/riptide_rviz/include/riptide_rviz/ServicePanel.hpp, riptide_rviz/riptide_rviz/src/ServicePanel.cpp, riptide_rviz/riptide_rviz/src/ServicePanel.ui
Adds service discovery, request-form or YAML construction, interface inspection, service invocation, timeout handling, and response display.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TreeStackTopic
  participant ControlPanel
  participant InteractiveMarkerServer

  TreeStackTopic->>ControlPanel: treeStackCallback(TreeStack msg)
  alt stack not empty
    ControlPanel->>InteractiveMarkerServer: erase setpoint marker
  else stack empty
    ControlPanel->>InteractiveMarkerServer: reinsert and apply setpoint marker
  end
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is a generic merge label and doesn't describe the RViz panel, config, and UI changes in this PR. Use a concise title that names the main change, such as adding Rosbag/Service panels and related RViz control updates.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
riptide_rviz/control_config_talos.rviz (3)

1109-1126: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

"Table" entry in Mapping Objects points to a dummy-detection topic, not a mapping topic.

Every sibling entry in this "Mapping Objects" group (Gate, Pill, Plug, Bandage, Warning, Helmet, Sos, Hammer and Wrench, Buoy, Compass, Torpedo, Bin Target 1/2) subscribes to /talos/mapping/*. This "Table" entry instead uses /talos/dummydetections/table — the exact same topic used by the separate "Table" entry in the "Dummy Detections" group (line 2125). This looks like a copy-paste error; the fused mapping pose for the table will never be displayed here.

🔧 Suggested fix
           Topic:
             Depth: 5
             Durability Policy: Volatile
             Filter size: 10
             History Policy: Keep Last
             Reliability Policy: Reliable
-            Value: /talos/dummydetections/table
+            Value: /talos/mapping/table
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/control_config_talos.rviz` around lines 1109 - 1126, The “Table”
item in the Mapping Objects group is subscribed to the wrong topic and should
match the other mapping entries. Update the Topic value for the Table entry in
control_config_talos.rviz so it uses the mapping namespace instead of the
dummy-detections topic, aligning it with the other Mapping Objects entries and
avoiding duplication with the separate Table item in the Dummy Detections group.

2605-2651: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Duplicate topic: "Fire Hole Small" and "Fire Hole Large" both subscribe to the same "_large" topic.

Name: Fire Hole Small (line 2605) and Name: Fire Hole Large (line 2640) both use Value: /talos/dummydetections/torpedo_fire_hole_large. Compare with the correctly-differentiated sibling pair "Blood Hole Large"/"Blood Hole Small", which use distinct _large/_small topics. The "Fire Hole Small" display will never show actual small-hole detections, and both panels will duplicate the "large" hole data.

🐛 Suggested fix
           Topic:
             Depth: 5
             Durability Policy: Volatile
             Filter size: 10
             History Policy: Keep Last
             Reliability Policy: Reliable
-            Value: /talos/dummydetections/torpedo_fire_hole_large
+            Value: /talos/dummydetections/torpedo_fire_hole_small
           Value: true

(applies to the "Fire Hole Small" entry at line 2615; the "Fire Hole Large" entry at line 2650 can keep the _large topic)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/control_config_talos.rviz` around lines 2605 - 2651, The “Fire
Hole Small” display is subscribed to the same detection topic as “Fire Hole
Large,” so the small and large views duplicate the large-hole data. Update the
topic used by the Fire Hole Small entry in the rviz config to the corresponding
small-hole topic, following the pattern already used by the Blood Hole
Small/Large displays. Keep the Fire Hole Large entry on the _large topic and
verify the two Fire Hole displays reference distinct topics.

730-741: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Rename the gate mapping displays to match the new object names

Gate Shark/Gate Saw still use /talos/mapping/gate_shark and /talos/mapping/gate_saw here, while markers.yaml and the dummy-detections entries already use Gate Repair/Gate Rescue with gate_repair/gate_rescue. Update these two RViz entries to keep the mapping config consistent. [lines 730-741, 764-776]

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/control_config_talos.rviz` around lines 730 - 741, The RViz gate
mapping display entries are still using the old object names and topics, so
update the two display blocks in control_config_talos.rviz for the Gate
Shark/Gate Saw mappings to match the new naming used elsewhere. In the relevant
RViz entries, rename the display labels to Gate Repair and Gate Rescue and
change their Topic Value fields from the old gate_shark/gate_saw mappings to the
corresponding gate_repair/gate_rescue topics so the configuration stays
consistent with markers.yaml and the dummy-detections data.
🧹 Nitpick comments (3)
riptide_rviz/riptide_rviz/src/OverlayDisplay.cpp (2)

115-116: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Typo in comment.

"JLog" should be "Log".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/riptide_rviz/src/OverlayDisplay.cpp` around lines 115 - 116, The
comment on logUiScale has a typo: “JLog” should be “Log”. Update the nearby
comment in OverlayDisplay.cpp so it correctly says “Log info about the ui
scaling,” keeping the function name logUiScale unchanged.

266-267: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Unused QFontMetrics fm left after removing text_rect computation.

fm is declared but no longer used since the bounding-rect computation was removed. This will trigger an unused-variable warning (and potential -Werror build failure depending on compiler flags).

🧹 Proposed fix
-            QStaticText only_wrapped_text(color_wrapped_text.c_str());
-            QFontMetrics fm(painter.fontMetrics());
+            QStaticText only_wrapped_text(color_wrapped_text.c_str());
             painter.drawStaticText(config.x_ + 1, config.y_ + 1, static_shadow);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/riptide_rviz/src/OverlayDisplay.cpp` around lines 266 - 267, The
OverlayDisplay::drawText path has an unused QFontMetrics fm declaration left
behind after removing the text_rect calculation, which can trigger warnings or
break builds with -Werror. Remove the redundant fm variable from the block that
creates only_wrapped_text, and keep the wrapping/rendering logic in
OverlayDisplay.cpp using only the symbols that are still needed.
riptide_rviz/riptide_rviz/src/MissionPanel.cpp (1)

29-31: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Qt::NoFocus removes keyboard access to the tree selector.

Setting btSelect (a QComboBox) to Qt::NoFocus prevents it from receiving keyboard focus at all — it can no longer be tabbed to or operated via keyboard, only by mouse click. If the intent is just to suppress the focus-rectangle highlight rather than block keyboard interaction entirely, consider Qt::ClickFocus combined with a stylesheet override (e.g., QComboBox:focus { outline: none; }) instead of Qt::NoFocus.

♻️ Suggested alternative preserving keyboard access
-        // dont want random highlighting of the tree list
-        uiPanel->btSelect->setFocusPolicy(Qt::NoFocus);
+        // dont want random highlighting of the tree list, but still allow keyboard use
+        uiPanel->btSelect->setFocusPolicy(Qt::ClickFocus);
+        uiPanel->btSelect->setStyleSheet("QComboBox:focus { outline: none; }");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/riptide_rviz/src/MissionPanel.cpp` around lines 29 - 31, The
focus setting on btSelect in MissionPanel is blocking keyboard navigation by
using Qt::NoFocus. Update the MissionPanel setup so the QComboBox can still
receive keyboard focus, and use a styling approach or a less restrictive focus
policy to suppress the visual focus highlight instead. Keep the change localized
to the btSelect configuration in MissionPanel.cpp.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@riptide_rviz/riptide_rviz/python/MarkerPublisher.py`:
- Around line 302-324: Avoid mutating the aliased pose in place in the marker
publishing path: in the logic around ghost pose handling, `ghost.pose` is shared
with `self.latestOdom.pose.pose` / `self.latestSetpt`, so subtracting the
rotated base-link offset directly changes the stored source message and causes
repeated drift on later ticks. Update `MarkerPublisher` so it copies the pose
into a fresh `Pose`/`Point` object before applying the `v_world` offset, and
then append that independent marker pose instead of modifying the original.

In `@riptide_rviz/riptide_rviz/src/OverlayDisplay.cpp`:
- Around line 228-234: The font sizing in OverlayDisplay::paintText is not using
the same DPI scaling as the overlay dimensions, so text stays visually smaller
on high-DPI displays. Update the font setup in paintText to apply
getUiScaleFactor() consistently when calling QFont::setPixelSize, using the same
scale logic already used by updateWidth() and updateHeight(), and make sure the
other paintText occurrence uses the same adjusted sizing path.
- Around line 102-113: The UI scaling logic in getUiScaleFactor() is using
QGuiApplication::primaryScreen() and combining devicePixelRatio with
logicalDotsPerInch(), which can mis-scale overlays on multi-monitor setups.
Update the scale source to use the RViz render window’s owning screen/window
instead of the primary screen, and adjust the calculation so DPR and logical DPI
are not blindly merged unless there’s a platform-specific need. Keep the change
localized to getUiScaleFactor() in OverlayDisplay.cpp and preserve the existing
high-DPI fallback behavior.

---

Outside diff comments:
In `@riptide_rviz/control_config_talos.rviz`:
- Around line 1109-1126: The “Table” item in the Mapping Objects group is
subscribed to the wrong topic and should match the other mapping entries. Update
the Topic value for the Table entry in control_config_talos.rviz so it uses the
mapping namespace instead of the dummy-detections topic, aligning it with the
other Mapping Objects entries and avoiding duplication with the separate Table
item in the Dummy Detections group.
- Around line 2605-2651: The “Fire Hole Small” display is subscribed to the same
detection topic as “Fire Hole Large,” so the small and large views duplicate the
large-hole data. Update the topic used by the Fire Hole Small entry in the rviz
config to the corresponding small-hole topic, following the pattern already used
by the Blood Hole Small/Large displays. Keep the Fire Hole Large entry on the
_large topic and verify the two Fire Hole displays reference distinct topics.
- Around line 730-741: The RViz gate mapping display entries are still using the
old object names and topics, so update the two display blocks in
control_config_talos.rviz for the Gate Shark/Gate Saw mappings to match the new
naming used elsewhere. In the relevant RViz entries, rename the display labels
to Gate Repair and Gate Rescue and change their Topic Value fields from the old
gate_shark/gate_saw mappings to the corresponding gate_repair/gate_rescue topics
so the configuration stays consistent with markers.yaml and the dummy-detections
data.

---

Nitpick comments:
In `@riptide_rviz/riptide_rviz/src/MissionPanel.cpp`:
- Around line 29-31: The focus setting on btSelect in MissionPanel is blocking
keyboard navigation by using Qt::NoFocus. Update the MissionPanel setup so the
QComboBox can still receive keyboard focus, and use a styling approach or a less
restrictive focus policy to suppress the visual focus highlight instead. Keep
the change localized to the btSelect configuration in MissionPanel.cpp.

In `@riptide_rviz/riptide_rviz/src/OverlayDisplay.cpp`:
- Around line 115-116: The comment on logUiScale has a typo: “JLog” should be
“Log”. Update the nearby comment in OverlayDisplay.cpp so it correctly says “Log
info about the ui scaling,” keeping the function name logUiScale unchanged.
- Around line 266-267: The OverlayDisplay::drawText path has an unused
QFontMetrics fm declaration left behind after removing the text_rect
calculation, which can trigger warnings or break builds with -Werror. Remove the
redundant fm variable from the block that creates only_wrapped_text, and keep
the wrapping/rendering logic in OverlayDisplay.cpp using only the symbols that
are still needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9f9c43fc-f061-48a7-aa0d-7f9fea5fc22b

📥 Commits

Reviewing files that changed from the base of the PR and between 1c1fe45 and bc9df4d.

⛔ Files ignored due to path filters (42)
  • riptide_meshes/meshes/bin/Task03_DropBRUVS.png is excluded by !**/*.png
  • riptide_meshes/meshes/bin/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/bin_magnet/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/bin_vinyl/Task3_Blood_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/bin_vinyl/Task3_Fire_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/bin_vinyl/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/gate_repair/Task1_SurveyRepair_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/gate_repair/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/gate_rescue/Task1_SearchRescue_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/gate_rescue/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/octagon_buoy/Task5_Search_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/octagon_buoy/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/octagon_compass/Task5_Survey_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/octagon_compass/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/octagon_hammer_and_wrench/Task5_Repair_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/octagon_hammer_and_wrench/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/octagon_sos/Task5_Rescue_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/octagon_sos/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/reefshark/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/sawfish/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/table/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/table_bandage/Task5_BandAid_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/table_bandage/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/table_basket_helmet/Task5_RedCross_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/table_basket_helmet/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/table_basket_pink/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/table_basket_warning/Task5_Warning_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/table_basket_warning/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/table_basket_yellow/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/table_bottle_pink/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/table_bottle_yellow/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/table_nut_and_bolt/Task5_NutBolt_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/table_nut_and_bolt/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/table_pill/Task5_Pill_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/table_pill/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/table_plug/Task5_Electric_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/table_plug/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/table_spoon_pink/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/table_spoon_yellow/model.dae is excluded by !**/*.dae
  • riptide_meshes/meshes/torpedo/Task04_Tagging_01.png is excluded by !**/*.png
  • riptide_meshes/meshes/torpedo/Task4_ver1_Fixed.png is excluded by !**/*.png
  • riptide_meshes/meshes/torpedo/model.dae is excluded by !**/*.dae
📒 Files selected for processing (11)
  • riptide_rviz/control_config_talos.rviz
  • riptide_rviz/riptide_rviz/config/markers.yaml
  • riptide_rviz/riptide_rviz/include/riptide_rviz/ControlPanel.hpp
  • riptide_rviz/riptide_rviz/include/riptide_rviz/MappingPanel.hpp
  • riptide_rviz/riptide_rviz/python/MarkerPublisher.py
  • riptide_rviz/riptide_rviz/src/ControlPanel.cpp
  • riptide_rviz/riptide_rviz/src/MappingPanel.cpp
  • riptide_rviz/riptide_rviz/src/MappingPanel.ui
  • riptide_rviz/riptide_rviz/src/MissionPanel.cpp
  • riptide_rviz/riptide_rviz/src/OverlayDisplay.cpp
  • riptide_rviz/riptide_rviz/src/ParamPanel.cpp

Comment on lines +302 to 324

ghostBaseLinkPose = Pose()
ghostBaseLinkPose.position.x = ghost.pose.position.x
ghostBaseLinkPose.position.y = ghost.pose.position.y
ghostBaseLinkPose.position.z = ghost.pose.position.z
ghostBaseLinkPose.orientation.w = ghost.pose.orientation.w
ghostBaseLinkPose.orientation.x = ghost.pose.orientation.x
ghostBaseLinkPose.orientation.y = ghost.pose.orientation.y
ghostBaseLinkPose.orientation.z = ghost.pose.orientation.z

# Rotate the base_link offset vector from the robot frame
# into the world frame using the robot’s orientation.
q = [ghost.pose.orientation.w, ghost.pose.orientation.x, ghost.pose.orientation.y, ghost.pose.orientation.z]
v = [float(self.baseLinkOffset[0]), float(self.baseLinkOffset[1]), float(self.baseLinkOffset[2])]
v_as_quat = [0.0, v[0], v[1], v[2]]
q_conj = [q[0], -q[1], -q[2], -q[3]]
v_world = qmult(qmult(q, v_as_quat), q_conj)

# translates the ghost pose so the base_link is correctly positioned relative to origin
ghost.pose.position.x = ghost.pose.position.x - v_world[1]
ghost.pose.position.y = ghost.pose.position.y - v_world[2]
ghost.pose.position.z = ghost.pose.position.z - v_world[3]
array.markers.append(ghost)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm that assigning a message sub-pose does not deep-copy (mutation propagates back to source).
python - <<'PY'
try:
    from nav_msgs.msg import Odometry
    from visualization_msgs.msg import Marker
    o = Odometry()
    m = Marker()
    m.pose = o.pose.pose          # same assignment pattern as MarkerPublisher line 278
    m.pose.position.x = 5.0
    print("source mutated:", o.pose.pose.position.x == 5.0)
except Exception as e:
    print("env unavailable:", e)
PY

Repository: osu-uwrt/riptide_gui

Length of output: 202


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the target file and inspect the relevant section with line numbers.
git ls-files 'riptide_rviz/riptide_rviz/python/MarkerPublisher.py'
wc -l riptide_rviz/riptide_rviz/python/MarkerPublisher.py
sed -n '250,340p' riptide_rviz/riptide_rviz/python/MarkerPublisher.py

# Find related usages of latestOdom/latestSetpt and pose assignment patterns.
rg -n "latestOdom|latestSetpt|ghost\.pose|baseLinkOffset|ghostBaseLinkPose" riptide_rviz/riptide_rviz/python/MarkerPublisher.py

Repository: osu-uwrt/riptide_gui

Length of output: 7357


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path('riptide_rviz/riptide_rviz/python/MarkerPublisher.py')
text = p.read_text()
for needle in [
    'ghost.pose = self.latestOdom.pose.pose',
    'ghost.pose = self.latestSetpt',
    'ghostBaseLinkPose = Pose()',
    'ghost.pose.position.x = ghost.pose.position.x - v_world[1]',
]:
    print(needle, '=>', needle in text)
PY

Repository: osu-uwrt/riptide_gui

Length of output: 345


🌐 Web query:

ROS 2 Python generated message field assignment stores a reference not a deep copy rosidl_generator_py message semantics

💡 Result:

In ROS 2 Python, message field assignment directly via class properties does not perform a deep copy; it stores a reference to the assigned object [1][2][3]. The generated Python code for ROS 2 messages uses standard Python property setters [1][2][3]. These setters enforce type constraints (such as verifying that a provided value matches the expected ROS message type) [1][2][3], but they do not internally clone or deep-copy the object being assigned [2][3]. Consequently, if you assign a mutable object (like a list or a nested message) to a field, modifying that original object elsewhere in your code will also affect the data stored inside the ROS 2 message [2][3]. Regarding helper utilities: - The common utility function set_message_fields, located in the rosidl_runtime_py package, is frequently used to populate message fields from dictionaries [4]. Historically, this function has been noted for modifying input dictionaries or objects during the population process [5][6]. - Recent updates (e.g., Pull Request #34 in rosidl_runtime_py) have addressed safety concerns by implementing deepcopy operations within set_message_fields to prevent unintended side effects on user-provided input data [5][6]. In summary, direct assignment to a message attribute is a reference assignment, and developers should be mindful of mutability when handling nested messages or arrays [1][2]. When using utility functions like set_message_fields, verify the version and behavior of your environment regarding deep copying to ensure data integrity [5][6].

Citations:


Avoid mutating the aliased pose in place. ghost.pose points at self.latestOdom.pose.pose / self.latestSetpt, so subtracting v_world here also changes the stored message. That makes the offset accumulate on subsequent timer ticks and drifts both the marker and the published ghost/base_link transform. Assign a fresh Pose/Point before applying the offset.

🧰 Tools
🪛 Ruff (0.15.20)

[warning] 313-313: Comment contains ambiguous (RIGHT SINGLE QUOTATION MARK). Did you mean ``` (GRAVE ACCENT)?

(RUF003)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/riptide_rviz/python/MarkerPublisher.py` around lines 302 - 324,
Avoid mutating the aliased pose in place in the marker publishing path: in the
logic around ghost pose handling, `ghost.pose` is shared with
`self.latestOdom.pose.pose` / `self.latestSetpt`, so subtracting the rotated
base-link offset directly changes the stored source message and causes repeated
drift on later ticks. Update `MarkerPublisher` so it copies the pose into a
fresh `Pose`/`Point` object before applying the `v_world` offset, and then
append that independent marker pose instead of modifying the original.

Source: Linters/SAST tools

Comment on lines +102 to +113
// For high dpi displays
static float getUiScaleFactor()
{
QScreen* screen = QGuiApplication::primaryScreen();
if (!screen) return 1.0f;

const float dpr = static_cast<float>(screen->devicePixelRatio());
const float dpi = static_cast<float>(screen->logicalDotsPerInch() / 96.0);

const float s = std::max(dpr, dpi);
return std::max(1.0f, s);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Qt QScreen devicePixelRatio vs logicalDotsPerInch relationship for HiDPI scaling on X11/Wayland/Windows

💡 Result:

In Qt, logicalDotsPerInch and devicePixelRatio serve distinct purposes in the framework's HiDPI scaling architecture [1][2][3]. Relationship and Definitions Qt operates on a coordinate system of device-independent pixels (DIPs) [4][3]. These are mapped to physical screen pixels using a scale factor, known as the device pixel ratio (DPR) [4][3]. - devicePixelRatio (QScreen::devicePixelRatio or QWindow::devicePixelRatio): This is the effective scale factor representing the ratio between physical screen pixels and device-independent pixels [1][5][3]. It is often a product of the native OS scale factor (provided by the platform) and any Qt-specific scale factor (e.g., set via QT_SCALE_FACTOR) [2][3][6]. - logicalDotsPerInch: This value is used primarily to convert font sizes and user interface element dimensions (expressed in points or other logical units) into device-independent pixels [1][5]. It is often derived from user-settable desktop environment settings [1]. Key Interactions Qt calculates the necessary devicePixelRatio by comparing the target display's logical DPI to a reference "base" DPI (typically 96 on X11) [2][3]. When an OS reports a scale factor via DPI (e.g., 144 DPI), Qt translates this into a devicePixelRatio [2][3]. Platform-Specific Behavior - X11: Often provides only global logical DPI or per-screen physical DPI [2][3]. Because neither is a direct native scale factor, HiDPI configuration on X11 is frequently more complex than on other platforms [2][3]. QT_USE_PHYSICAL_DPI can be used to force Qt to use physical DPI if logical DPI is unavailable or incorrect [2][3]. - Wayland/Windows: These platforms generally provide native scaling information that Qt integrates directly into its devicePixelRatio calculation [3][6]. On Wayland, QWindow::devicePixelRatio may incorporate fractional scaling, which may differ from QScreen::devicePixelRatio depending on window-specific surface resolution settings [1][5]. Best Practices - Prefer QWindow::devicePixelRatio over QScreen::devicePixelRatio when a window instance is available [1][5]. QWindow::devicePixelRatio accurately tracks the DPR as the window moves between displays with different properties [2][3]. - logicalDotsPerInch is appropriate for UI layout and font scaling logic, whereas devicePixelRatio is intended for low-level drawing (e.g., OpenGL) and mapping coordinate systems to physical buffers [2][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== File outline ==\n'
ast-grep outline riptide_rviz/riptide_rviz/src/OverlayDisplay.cpp --view expanded || true

printf '\n== Relevant excerpt ==\n'
sed -n '1,220p' riptide_rviz/riptide_rviz/src/OverlayDisplay.cpp | cat -n

printf '\n== Search for getUiScaleFactor usages and screen/window APIs ==\n'
rg -n "getUiScaleFactor|primaryScreen|screen\(|windowHandle\(|QScreen|devicePixelRatio|logicalDotsPerInch" riptide_rviz/riptide_rviz/src riptide_rviz/riptide_rviz/include || true

Repository: osu-uwrt/riptide_gui

Length of output: 11723


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== Call sites around getUiScaleFactor ==\n'
sed -n '330,400p' riptide_rviz/riptide_rviz/src/OverlayDisplay.cpp | cat -n

printf '\n== OverlayDisplay declaration ==\n'
ast-grep outline riptide_rviz/riptide_rviz/include/riptide_rviz/OverlayDisplay.hpp --view expanded || true
sed -n '1,260p' riptide_rviz/riptide_rviz/include/riptide_rviz/OverlayDisplay.hpp | cat -n

printf '\n== Search for window/screen access in overlay-related code ==\n'
rg -n "windowHandle\(|screen\(\)|QWidget|QWindow|QGuiApplication::primaryScreen|QScreen" riptide_rviz/riptide_rviz/include riptide_rviz/riptide_rviz/src || true

Repository: osu-uwrt/riptide_gui

Length of output: 17239


Scale from the RViz render window, not the primary screen. primaryScreen() can mis-size the overlay on multi-monitor setups, and max(devicePixelRatio(), logicalDotsPerInch()/96) can over-scale on platforms where Qt already folds DPI scaling into DPR. Use the screen/window that owns the RViz surface, and keep DPR and logical DPI separate unless there’s a platform-specific reason to combine them.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/riptide_rviz/src/OverlayDisplay.cpp` around lines 102 - 113, The
UI scaling logic in getUiScaleFactor() is using QGuiApplication::primaryScreen()
and combining devicePixelRatio with logicalDotsPerInch(), which can mis-scale
overlays on multi-monitor setups. Update the scale source to use the RViz render
window’s owning screen/window instead of the primary screen, and adjust the
calculation so DPR and logical DPI are not blindly merged unless there’s a
platform-specific need. Keep the change localized to getUiScaleFactor() in
OverlayDisplay.cpp and preserve the existing high-DPI fallback behavior.

Comment on lines 228 to 234
if (config.font_size_ != 0) {
// QFont font = painter.font();
QFont font(config.font_name_.length() > 0 ? config.font_name_.c_str() : "Liberation Sans");
font.setPointSize(config.font_size_);
font.setPixelSize(std::max(config.font_size_, 1));
font.setBold(true);
painter.setFont(font);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Font pixel size is not scaled while texture dimensions are — inconsistent DPI scaling.

updateWidth()/updateHeight() multiply the configured width/height by getUiScaleFactor(), but paintText() still uses config.font_size_ unscaled via setPixelSize(). Since the overlay canvas grows on high-DPI displays but the font size doesn't, text will render visually smaller relative to the overlay/anchors than before this change, undermining the intent of the DPI-scaling feature.

💡 Proposed fix: scale font size consistently with texture dimensions
         if (config.font_size_ != 0) {
             // QFont font = painter.font();
             QFont font(config.font_name_.length() > 0 ? config.font_name_.c_str() : "Liberation Sans");
-            font.setPixelSize(std::max(config.font_size_, 1));
+            font.setPixelSize(std::max(static_cast<int>(std::lround(config.font_size_ * getUiScaleFactor())), 1));
             font.setBold(true);
             painter.setFont(font);
         }

Also applies to: 368-378

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/riptide_rviz/src/OverlayDisplay.cpp` around lines 228 - 234, The
font sizing in OverlayDisplay::paintText is not using the same DPI scaling as
the overlay dimensions, so text stays visually smaller on high-DPI displays.
Update the font setup in paintText to apply getUiScaleFactor() consistently when
calling QFont::setPixelSize, using the same scale logic already used by
updateWidth() and updateHeight(), and make sure the other paintText occurrence
uses the same adjusted sizing path.

@coderabbitai coderabbitai Bot 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
riptide_rviz/control_config_talos.rviz (1)

2621-2634: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

"Fire Hole Small" subscribes to the _large topic.

Both Fire Hole Small (Line 2634) and Fire Hole Large (Line 2669) subscribe to /talos/dummydetections/torpedo_fire_hole_large. The small variant almost certainly should point to torpedo_fire_hole_small (matching the Blood Hole pattern at Lines 2564/2599). As written, the small-hole marker will never render its own detection.

🐛 Proposed fix
-            Value: /talos/dummydetections/torpedo_fire_hole_large
+            Value: /talos/dummydetections/torpedo_fire_hole_small
           Value: true

(apply to the Fire Hole Small entry ending at Line 2634)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/control_config_talos.rviz` around lines 2621 - 2634, Update the
Topic Value in the “Fire Hole Small” marker entry to subscribe to
/talos/dummydetections/torpedo_fire_hole_small, while leaving the “Fire Hole
Large” entry pointed at the large topic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@riptide_rviz/control_config_talos.rviz`:
- Around line 2621-2634: Update the Topic Value in the “Fire Hole Small” marker
entry to subscribe to /talos/dummydetections/torpedo_fire_hole_small, while
leaving the “Fire Hole Large” entry pointed at the large topic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 56c79325-e15c-4516-aac1-981a6d80c0c0

📥 Commits

Reviewing files that changed from the base of the PR and between bc9df4d and 26cf22b.

📒 Files selected for processing (3)
  • riptide_rviz/control_config_talos.rviz
  • riptide_rviz/riptide_rviz/include/riptide_rviz/MissionPanel.hpp
  • riptide_rviz/riptide_rviz/src/MissionPanel.cpp

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
riptide_rviz/riptide_rviz/src/ElectricalPanel.ui (1)

481-937: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

pingerFreq5 carries stray custom styling that the other four buttons don't.

Only pingerFreq5 defines a full custom palette (blue button, black text) plus an italic font, while pingerFreq1pingerFreq4 use defaults. This appears to be an accidental Qt Designer artifact and will render the fifth frequency button inconsistently with its siblings. Consider dropping the palette/font overrides so all five buttons match.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/riptide_rviz/src/ElectricalPanel.ui` around lines 481 - 937,
Remove the custom palette and font properties from the pingerFreq5 widget,
including its blue palette and italic font override. Keep its text and checkable
properties unchanged so it uses the same default styling as
pingerFreq1–pingerFreq4.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@riptide_rviz/riptide_rviz/src/ElectricalPanel.ui`:
- Around line 481-937: Remove the custom palette and font properties from the
pingerFreq5 widget, including its blue palette and italic font override. Keep
its text and checkable properties unchanged so it uses the same default styling
as pingerFreq1–pingerFreq4.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2764eebb-170e-4556-b778-5dba8f02e0d2

📥 Commits

Reviewing files that changed from the base of the PR and between 26cf22b and 256209d.

📒 Files selected for processing (3)
  • riptide_rviz/riptide_rviz/include/riptide_rviz/ElectricalPanel.hpp
  • riptide_rviz/riptide_rviz/src/ElectricalPanel.cpp
  • riptide_rviz/riptide_rviz/src/ElectricalPanel.ui

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@riptide_rviz/riptide_rviz/src/RosbagPanel.cpp`:
- Around line 210-213: Update RosbagPanel::refreshTopics to store the result of
getRosNodeAbstraction().lock() and return early when it is null, before calling
get_raw_node(). Preserve the existing topic refresh flow when the ROS node
abstraction is available.

In `@riptide_rviz/riptide_rviz/src/ServicePanel.cpp`:
- Around line 113-116: Update ServicePanel::refreshServices to store the result
of getRosNodeAbstraction().lock(), check it for null, and return before calling
get_raw_node when unavailable. Preserve the existing service discovery flow when
the abstraction is valid, following the guard pattern used by
RosbagPanel::refreshTopics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c699200c-8628-4d95-a6f8-f2c2bd4f5be0

📥 Commits

Reviewing files that changed from the base of the PR and between 256209d and af0eab5.

📒 Files selected for processing (7)
  • riptide_rviz/riptide_rviz/config/rosbag_presets.yaml
  • riptide_rviz/riptide_rviz/include/riptide_rviz/RosbagPanel.hpp
  • riptide_rviz/riptide_rviz/include/riptide_rviz/ServicePanel.hpp
  • riptide_rviz/riptide_rviz/src/RosbagPanel.cpp
  • riptide_rviz/riptide_rviz/src/RosbagPanel.ui
  • riptide_rviz/riptide_rviz/src/ServicePanel.cpp
  • riptide_rviz/riptide_rviz/src/ServicePanel.ui

Comment on lines +210 to +213
void RosbagPanel::refreshTopics()
{
auto node = getDisplayContext()->getRosNodeAbstraction().lock()->get_raw_node();
const auto topicsAndTypes = node->get_topic_names_and_types();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Guard against a null ROS node abstraction.

getRosNodeAbstraction().lock() can return a null shared_ptr (e.g. during teardown or before the node is bound), and dereferencing it via ->get_raw_node() would crash the panel. A cheap guard avoids the segfault.

🛡️ Proposed guard
 void RosbagPanel::refreshTopics()
 {
-    auto node = getDisplayContext()->getRosNodeAbstraction().lock()->get_raw_node();
+    auto nodeAbstraction = getDisplayContext()->getRosNodeAbstraction().lock();
+    if (!nodeAbstraction)
+    {
+        setStatus("ROS node not available yet.", true);
+        return;
+    }
+    auto node = nodeAbstraction->get_raw_node();
     const auto topicsAndTypes = node->get_topic_names_and_types();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void RosbagPanel::refreshTopics()
{
auto node = getDisplayContext()->getRosNodeAbstraction().lock()->get_raw_node();
const auto topicsAndTypes = node->get_topic_names_and_types();
void RosbagPanel::refreshTopics()
{
auto nodeAbstraction = getDisplayContext()->getRosNodeAbstraction().lock();
if (!nodeAbstraction)
{
setStatus("ROS node not available yet.", true);
return;
}
auto node = nodeAbstraction->get_raw_node();
const auto topicsAndTypes = node->get_topic_names_and_types();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/riptide_rviz/src/RosbagPanel.cpp` around lines 210 - 213, Update
RosbagPanel::refreshTopics to store the result of getRosNodeAbstraction().lock()
and return early when it is null, before calling get_raw_node(). Preserve the
existing topic refresh flow when the ROS node abstraction is available.

Comment on lines +113 to +116
void ServicePanel::refreshServices()
{
auto node = getDisplayContext()->getRosNodeAbstraction().lock()->get_raw_node();
const auto namesAndTypes = node->get_service_names_and_types();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Guard against a null ROS node abstraction.

Same pattern as RosbagPanel::refreshTopics: getRosNodeAbstraction().lock() may return null and dereferencing it here would crash the panel.

🛡️ Proposed guard
 void ServicePanel::refreshServices()
 {
-    auto node = getDisplayContext()->getRosNodeAbstraction().lock()->get_raw_node();
+    auto nodeAbstraction = getDisplayContext()->getRosNodeAbstraction().lock();
+    if (!nodeAbstraction)
+    {
+        setStatus("ROS node not available yet.", true);
+        return;
+    }
+    auto node = nodeAbstraction->get_raw_node();
     const auto namesAndTypes = node->get_service_names_and_types();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void ServicePanel::refreshServices()
{
auto node = getDisplayContext()->getRosNodeAbstraction().lock()->get_raw_node();
const auto namesAndTypes = node->get_service_names_and_types();
void ServicePanel::refreshServices()
{
auto nodeAbstraction = getDisplayContext()->getRosNodeAbstraction().lock();
if (!nodeAbstraction)
{
setStatus("ROS node not available yet.", true);
return;
}
auto node = nodeAbstraction->get_raw_node();
const auto namesAndTypes = node->get_service_names_and_types();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/riptide_rviz/src/ServicePanel.cpp` around lines 113 - 116,
Update ServicePanel::refreshServices to store the result of
getRosNodeAbstraction().lock(), check it for null, and return before calling
get_raw_node when unavailable. Preserve the existing service discovery flow when
the abstraction is valid, following the guard pattern used by
RosbagPanel::refreshTopics.

@coderabbitai coderabbitai Bot 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
riptide_rviz/control_config_talos.rviz (2)

2163-2174: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Fire Hole Small subscribes to the torpedo_fire_hole_large topic.

The display is named "Fire Hole Small" but its topic (line 2173) is /talos/dummydetections/torpedo_fire_hole_large — identical to the "Fire Hole Large" display below it (line 2208). The Blood Hole Small/Blood Hole Large pair confirms the expected pattern: small should use _small. Both displays will render identical data.

🔧 Proposed fix
           Name: Fire Hole Small
           Shaft Length: 1
           Shaft Radius: 0.05000000074505806
           Shape: Arrow
           Topic:
             Depth: 5
             Durability Policy: Volatile
             Filter size: 10
             History Policy: Keep Last
             Reliability Policy: Reliable
-            Value: /talos/dummydetections/torpedo_fire_hole_large
+            Value: /talos/dummydetections/torpedo_fire_hole_small
           Value: true
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/control_config_talos.rviz` around lines 2163 - 2174, Update the
`Fire Hole Small` display’s `Topic.Value` to subscribe to
`/talos/dummydetections/torpedo_fire_hole_small`, while leaving the `Fire Hole
Large` topic unchanged.

673-684: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Table in Mapping Objects subscribes to the wrong topic namespace.

All other displays in the Mapping Objects group use /talos/mapping/... topics, but Table uses /talos/dummydetections/table — the same topic as the Table display in the Dummy Detections group (line 1683). This is likely a copy-paste error that will show dummy detection data in the mapping section.

🔧 Proposed fix
           Name: Table
           Shaft Length: 1
           Shaft Radius: 0.05000000074505806
           Shape: Arrow
           Topic:
             Depth: 5
             Durability Policy: Volatile
             Filter size: 10
             History Policy: Keep Last
             Reliability Policy: Reliable
-            Value: /talos/dummydetections/table
+            Value: /talos/mapping/table
           Value: true
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@riptide_rviz/control_config_talos.rviz` around lines 673 - 684, Update the
Mapping Objects `Table` display’s `Topic.Value` from
`/talos/dummydetections/table` to the corresponding `/talos/mapping/...`
namespace, matching the topic pattern used by the other displays in that group;
leave the separate Dummy Detections `Table` unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@riptide_rviz/control_config_talos.rviz`:
- Around line 2163-2174: Update the `Fire Hole Small` display’s `Topic.Value` to
subscribe to `/talos/dummydetections/torpedo_fire_hole_small`, while leaving the
`Fire Hole Large` topic unchanged.
- Around line 673-684: Update the Mapping Objects `Table` display’s
`Topic.Value` from `/talos/dummydetections/table` to the corresponding
`/talos/mapping/...` namespace, matching the topic pattern used by the other
displays in that group; leave the separate Dummy Detections `Table` unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: be7afa1d-b50c-4604-9aa9-d3167ed51474

📥 Commits

Reviewing files that changed from the base of the PR and between af0eab5 and 8d0ad0a.

📒 Files selected for processing (2)
  • riptide_rviz/control_config_talos.rviz
  • riptide_rviz/riptide_rviz/plugins_description.xml

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.

3 participants