1414
1515"""Integration test for the unitree_go2_smartnav blueprint using replay data.
1616
17- Builds the smartnav pipeline (GO2Connection → OdomAdapter → PGO → CostMapper →
17+ Builds the smartnav pipeline (GO2Connection → PGO → CostMapper →
1818ReplanningAStarPlanner) in replay mode and verifies that data flows end-to-end:
19- - PGO receives scans and odom, publishes corrected_odometry + global_map
19+ - PGO receives scans and raw odom (PoseStamped) , publishes corrected_odometry + global_map
2020 - CostMapper receives global_map, publishes global_costmap
2121"""
2222
3434from dimos .msgs .nav_msgs .Odometry import Odometry
3535from dimos .msgs .nav_msgs .OccupancyGrid import OccupancyGrid
3636from dimos .msgs .sensor_msgs .PointCloud2 import PointCloud2
37- from dimos .navigation .smartnav .modules .odom_adapter .odom_adapter import odom_adapter
38- from dimos .navigation .smartnav .modules .pgo .pgo import PGO
37+ from dimos .navigation .loop_closure .pgo import PGO
3938from dimos .robot .unitree .go2 .blueprints .basic .unitree_go2_basic import unitree_go2_basic
4039from dimos .robot .unitree .go2 .connection import GO2Connection
4140
@@ -55,13 +54,12 @@ def smartnav_coordinator():
5554 n_workers = 1 ,
5655 )
5756
58- # Minimal pipeline: GO2Connection → OdomAdapter → PGO → CostMapper
57+ # Minimal pipeline: GO2Connection → PGO → CostMapper
5958 # Skip ReplanningAStarPlanner and WavefrontFrontierExplorer to avoid
6059 # needing a goal and cmd_vel sink.
6160 bp = autoconnect (
6261 unitree_go2_basic ,
6362 PGO .blueprint (),
64- odom_adapter (),
6563 cost_mapper (),
6664 ).global_config (
6765 n_workers = 1 ,
@@ -187,35 +185,25 @@ def test_costmapper_produces_costmap(self, smartnav_coordinator):
187185 msg = collector .messages [0 ]
188186 assert isinstance (msg , OccupancyGrid ), f"Expected OccupancyGrid, got { type (msg )} "
189187
190- def test_odom_adapter_converts_bidirectionally (self , smartnav_coordinator ):
191- """OdomAdapter should convert PoseStamped→Odometry and Odometry→ PoseStamped."""
188+ def test_pgo_produces_corrected_pose_stamped (self , smartnav_coordinator ):
189+ """PGO should publish corrected pose as PoseStamped on the odom output ."""
192190 coord = smartnav_coordinator
193191
194- from dimos .navigation .smartnav .modules .odom_adapter .odom_adapter import OdomAdapter
195-
196- adapter = None
192+ pgo_mod = None
197193 for mod in coord .all_modules :
198- if isinstance (mod , OdomAdapter ):
199- adapter = mod
194+ if isinstance (mod , PGO ):
195+ pgo_mod = mod
200196 break
201- assert adapter is not None , "OdomAdapter not found in coordinator"
197+ assert pgo_mod is not None , "PGO module not found in coordinator"
202198
203- # Collect outputs from both directions
204- odom_out = _StreamCollector ()
205- ps_out = _StreamCollector ()
206- adapter .odometry ._transport .subscribe (odom_out .callback )
207- adapter .odom ._transport .subscribe (ps_out .callback )
199+ collector = _StreamCollector ()
200+ pgo_mod .odom ._transport .subscribe (collector .callback )
208201
209202 coord .start ()
210203
211- # OdomAdapter.odometry (PoseStamped→Odometry) should fire from replay odom
212- assert odom_out .wait (count = 3 , timeout = 30 ), (
213- f"OdomAdapter did not produce Odometry output (got { len (odom_out .messages )} )"
214- )
215- assert isinstance (odom_out .messages [0 ], Odometry )
216-
217- # OdomAdapter.odom (Odometry→PoseStamped) fires when PGO publishes corrected_odometry
218- assert ps_out .wait (count = 1 , timeout = 30 ), (
219- f"OdomAdapter did not produce PoseStamped output (got { len (ps_out .messages )} )"
204+ assert collector .wait (count = 3 , timeout = 30 ), (
205+ f"PGO did not produce PoseStamped odom output (got { len (collector .messages )} )"
220206 )
221- assert isinstance (ps_out .messages [0 ], PoseStamped )
207+ msg = collector .messages [0 ]
208+ assert isinstance (msg , PoseStamped ), f"Expected PoseStamped, got { type (msg )} "
209+ assert msg .frame_id == "map"
0 commit comments