Skip to content

Commit 7e04728

Browse files
committed
feat: tidy the RViz display and ship the config with the package
- Rename the displays to semantic names: Map (prior), Live Scan, Local Map, Trajectory (/path), Localized Pose (/pcl_pose), and a new TF display so the frame chain is visible. - Render the live scan as a flat white cloud instead of a noisy rainbow, and color the prior map / local map consistently. - Fix a latent bringup bug: rviz/localization.rviz was referenced by quickstart.launch.py from package_share but the rviz/ directory was not in install(DIRECTORY ...), so the installed package could not load the config. Add rviz/ to the install list. - Add test/test_rviz_config.py (5 checks) pinning the config shape, defaults, flat-color scan, install coverage, and the quickstart reference. ctest 96/96.
1 parent f4899fb commit 7e04728

3 files changed

Lines changed: 100 additions & 15 deletions

File tree

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ install(DIRECTORY
313313
docs
314314
experiments
315315
param
316+
rviz
316317
DESTINATION share/${PROJECT_NAME}/
317318
)
318319

@@ -984,6 +985,12 @@ if(BUILD_TESTING)
984985
NAME global_localization_query
985986
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/test_global_localization_query.py
986987
)
988+
add_test(
989+
NAME rviz_config
990+
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/test_rviz_config.py
991+
)
992+
set_tests_properties(rviz_config PROPERTIES
993+
ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_SOURCE_DIR}")
987994
add_test(
988995
NAME g2_candidate_registration_rank_policy
989996
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/test_g2_candidate_registration_rank_policy.py

rviz/localization.rviz

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ Panels:
66
Expanded:
77
- /Global Options1
88
- /Status1
9+
- /Map (prior)1
10+
- /Live Scan1
11+
- /Trajectory (/path)1
12+
- /Localized Pose (/pcl_pose)1
913
Splitter Ratio: 0.5
1014
Tree Height: 617
1115
- Class: rviz_common/Selection
@@ -50,21 +54,21 @@ Visualization Manager:
5054
Axis: Z
5155
Channel Name: intensity
5256
Class: rviz_default_plugins/PointCloud2
53-
Color: 255; 255; 255
54-
Color Transformer: ""
57+
Color: 160; 160; 160
58+
Color Transformer: FlatColor
5559
Decay Time: 0
5660
Enabled: true
5761
Invert Rainbow: false
5862
Max Color: 255; 255; 255
5963
Max Intensity: 4096
6064
Min Color: 0; 0; 0
6165
Min Intensity: 0
62-
Name: PointCloud2
63-
Position Transformer: ""
66+
Name: Map (prior)
67+
Position Transformer: XYZ
6468
Selectable: true
6569
Size (Pixels): 3
6670
Size (m): 0.009999999776482582
67-
Style: Flat Squares
71+
Style: Points
6872
Topic:
6973
Depth: 5
7074
Durability Policy: Volatile
@@ -73,7 +77,7 @@ Visualization Manager:
7377
Reliability Policy: Reliable
7478
Value: /map
7579
Use Fixed Frame: true
76-
Use rainbow: true
80+
Use rainbow: false
7781
Value: true
7882
- Alpha: 1
7983
Autocompute Intensity Bounds: true
@@ -85,15 +89,15 @@ Visualization Manager:
8589
Channel Name: ring
8690
Class: rviz_default_plugins/PointCloud2
8791
Color: 255; 255; 255
88-
Color Transformer: Intensity
92+
Color Transformer: FlatColor
8993
Decay Time: 0
9094
Enabled: true
9195
Invert Rainbow: false
9296
Max Color: 255; 255; 255
9397
Max Intensity: 31
9498
Min Color: 0; 0; 0
9599
Min Intensity: 0
96-
Name: PointCloud2
100+
Name: Live Scan
97101
Position Transformer: XYZ
98102
Selectable: true
99103
Size (Pixels): 3
@@ -107,7 +111,7 @@ Visualization Manager:
107111
Reliability Policy: Reliable
108112
Value: /velodyne_points
109113
Use Fixed Frame: true
110-
Use rainbow: true
114+
Use rainbow: false
111115
Value: true
112116
- Alpha: 1
113117
Buffer Length: 1
@@ -119,7 +123,7 @@ Visualization Manager:
119123
Length: 0.30000001192092896
120124
Line Style: Lines
121125
Line Width: 0.029999999329447746
122-
Name: Path
126+
Name: Trajectory (/path)
123127
Offset:
124128
X: 0
125129
Y: 0
@@ -146,16 +150,16 @@ Visualization Manager:
146150
Axis: Z
147151
Channel Name: intensity
148152
Class: rviz_default_plugins/PointCloud2
149-
Color: 255; 255; 255
150-
Color Transformer: AxisColor
153+
Color: 0; 200; 255
154+
Color Transformer: FlatColor
151155
Decay Time: 0
152156
Enabled: true
153157
Invert Rainbow: false
154158
Max Color: 255; 255; 255
155159
Max Intensity: 0
156160
Min Color: 0; 0; 0
157161
Min Intensity: 0
158-
Name: PointCloud2
162+
Name: Local Map
159163
Position Transformer: XYZ
160164
Selectable: true
161165
Size (Pixels): 1
@@ -169,7 +173,7 @@ Visualization Manager:
169173
Reliability Policy: Reliable
170174
Value: /initial_map
171175
Use Fixed Frame: true
172-
Use rainbow: true
176+
Use rainbow: false
173177
Value: true
174178
- Alpha: 1
175179
Axes Length: 1
@@ -194,7 +198,7 @@ Visualization Manager:
194198
Enabled: true
195199
Head Length: 0.30000001192092896
196200
Head Radius: 0.10000000149011612
197-
Name: PoseWithCovariance
201+
Name: Localized Pose (/pcl_pose)
198202
Shaft Length: 1
199203
Shaft Radius: 0.05000000074505806
200204
Shape: Arrow
@@ -206,6 +210,19 @@ Visualization Manager:
206210
Reliability Policy: Reliable
207211
Value: /pcl_pose
208212
Value: true
213+
- Alpha: 1
214+
Class: rviz_default_plugins/TF
215+
Enabled: true
216+
Frame Timeout: 15
217+
Frames:
218+
All Enabled: true
219+
Marker Scale: 1
220+
Name: TF
221+
Show Arrows: true
222+
Show Axes: true
223+
Show Names: true
224+
Update Interval: 0
225+
Value: true
209226
Enabled: true
210227
Global Options:
211228
Background Color: 48; 48; 48

test/test_rviz_config.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env python3
2+
"""Regression guards for the user-facing RViz configuration.
3+
4+
The RViz config is the primary visualization surface for quickstart and the
5+
Nav2/standalone launches. These tests keep it parseable, keep the display names
6+
semantic, and keep it installed with the package (quickstart.launch.py loads it
7+
from the package share directory).
8+
"""
9+
10+
import re
11+
import unittest
12+
from pathlib import Path
13+
14+
import yaml
15+
16+
ROOT = Path(__file__).resolve().parents[1]
17+
RViz_PATH = ROOT / "rviz" / "localization.rviz"
18+
CMAKELISTS = ROOT / "CMakeLists.txt"
19+
QUICKSTART_LAUNCH = ROOT / "launch" / "quickstart.launch.py"
20+
21+
22+
class TestRvizConfig(unittest.TestCase):
23+
def test_config_is_valid_yaml(self):
24+
data = yaml.safe_load(RViz_PATH.read_text(encoding="utf-8"))
25+
manager = data["Visualization Manager"]
26+
self.assertEqual(manager["Global Options"]["Fixed Frame"], "map")
27+
displays = manager["Displays"]
28+
names = [d.get("Name") for d in displays]
29+
self.assertGreaterEqual(len(displays), 6)
30+
for expected in ("Map (prior)", "Live Scan", "Local Map",
31+
"Trajectory (/path)", "Localized Pose (/pcl_pose)", "TF"):
32+
self.assertIn(expected, names)
33+
34+
def test_key_displays_are_enabled(self):
35+
data = yaml.safe_load(RViz_PATH.read_text(encoding="utf-8"))
36+
displays = {d.get("Name"): d for d in data["Visualization Manager"]["Displays"]}
37+
for name in ("Live Scan", "Localized Pose (/pcl_pose)", "Trajectory (/path)"):
38+
self.assertTrue(displays[name]["Enabled"], f"{name} must be visible by default")
39+
40+
def test_scan_display_uses_flat_color(self):
41+
data = yaml.safe_load(RViz_PATH.read_text(encoding="utf-8"))
42+
scan = next(
43+
d for d in data["Visualization Manager"]["Displays"]
44+
if d.get("Name") == "Live Scan")
45+
self.assertEqual(scan["Color Transformer"], "FlatColor")
46+
self.assertFalse(scan["Use rainbow"])
47+
48+
def test_rviz_dir_is_installed_with_package(self):
49+
cmake = CMAKELISTS.read_text(encoding="utf-8")
50+
match = re.search(r"install\(DIRECTORY\s*(.*?)\s*DESTINATION share/\$\{PROJECT_NAME\}",
51+
cmake, re.DOTALL)
52+
self.assertIsNotNone(match, "install(DIRECTORY ... share) block not found")
53+
self.assertIn("rviz", match.group(1))
54+
55+
def test_quickstart_loads_config_from_package_share(self):
56+
source = QUICKSTART_LAUNCH.read_text(encoding="utf-8")
57+
self.assertIn('os.path.join(package_share, "rviz", "localization.rviz")', source)
58+
59+
60+
if __name__ == "__main__":
61+
unittest.main()

0 commit comments

Comments
 (0)