【ROS2】map话题里没有数据,RVIZ显示No map received

张开发
2026/4/15 11:13:03 15 分钟阅读

分享文章

【ROS2】map话题里没有数据,RVIZ显示No map received
【ROS2】map话题里没有数据RVIZ显示No map received背景排查命令汇总1. 检查是否存在地图话题2. 显示一条map数据3. . 查看map话题的信息4. 手动发布假数据给map5. 确认 SLAM Toolbox 当前订阅的话题6. 查看 /scan 的发布频率7. 检查 TF 变换8. 检查 SLAM Toolbox 的参数配置9. 确认 SLAM Toolbox 使用的 frame 名称10. 查看话题/scan 消息中的 frame_id11. 修改 SLAM Toolbox 参数12. 实时监控所有 TF 状态最后解决方案验证背景esp32将雷达数据透传到TCP的节点上在RVIZ上能看到发布的点云在执行了ros2 launch slam_toolbox online_async_launch.py命令后使用map_saver_cli保存地图报错$ ros2 run nav2_map_server map_saver_cli-fmy_house[INFO][1775206831.295357438][map_saver]: map_saver lifecyclenodelaunched. Waiting on external lifecycle transitions to activate See https://design.ros2.org/articles/node_lifecycle.htmlformoreinformation.[INFO][1775206831.302660644][map_saver]: Creating[INFO][1775206831.305790803][map_saver]: Configuring[INFO][1775206831.406237489][map_saver]: Saving map frommaptopic tomy_housefile[WARN][1775206831.406746843][map_saver]: Free threshold unspecified. Setting it to default value:0.250000[WARN][1775206831.408202269][map_saver]: Occupied threshold unspecified. Setting it to default value:0.650000[ERROR][1775206833.435196105][map_saver]: Failed to spin map subscription[INFO][1775206833.444451158][map_saver]: Destroying[ros2run]: Process exited with failure1上述报错Failed to spin map subscription 表示 map_saver_cli 尝试从 /map 话题接收地图消息但在默认的 3 秒内超时了。没有任何节点在发布地图数据。排查命令汇总1. 检查是否存在地图话题ros2 topic list|grepmap2. 显示一条map数据ros2 topicecho/map--once或者 ros2 topicecho/scan--once--fieldranges该命令应显示一条 nav_msgs/msg/OccupancyGrid 消息。如果一直卡住说明话题确实没有数据发布或者ros2 topicecho/scan--once--fieldranges该命令如果输出类似 [2.3, 2.5, …] 的数组 → 有数据问题在别处。该命令如果卡住无输出或报错 → 没有数据检查你的激光雷达驱动是否正常运行3. . 查看map话题的信息ros2 topic info /map如果看到 Publisher count: 1 且有数据类型 nav_msgs/msg/OccupancyGrid说明发布成功。接着 RViz 中的 Map 显示会从 No map received 变成正常地图。4. 手动发布假数据给mapros2 topic pub-r10/scan sensor_msgs/msg/LaserScan{header: {frame_id: laser_frame}, ranges: [10.0], angle_min: -1.57, angle_max: 1.57, angle_increment: 0.0174}5. 确认 SLAM Toolbox 当前订阅的话题ros2nodeinfo /slam_toolbox6. 查看 /scan 的发布频率ros2 topic hz /scan应该看到 10Hz 左右或你雷达的实际频率。如果显示 no messages received说明雷达没有发数据。7. 检查 TF 变换ros2 run tf2_tools view_frames.py evince frames.pdf在生成的 frames.pdf 中确认存在类似以下的变换链laser_frame → base_link → odom或者 laser_frame → base_footprint → odom如果缺少 laser_frame 到 base_link 的变换SLAM Toolbox 会一直等待不会发布 /map8. 检查 SLAM Toolbox 的参数配置ros2 param dump /slam_toolbox重点关注 scan_topic、base_frame、odom_frame。9. 确认 SLAM Toolbox 使用的 frame 名称ros2 param get /slam_toolbox base_frame ros2 param get /slam_toolbox odom_frame ros2 param get /slam_toolbox map_frame默认通常为base_frame : “base_footprint” 或 “base_link”odom_frame : “odom”map_frame : “map”10. 查看话题/scan 消息中的 frame_idros2 topicecho/scan--once--fieldheader.frame_id11. 修改 SLAM Toolbox 参数ros2 paramset/slam_toolbox base_frame base_link设置base_frame 的参数base_link。比如TF 树中有 laser_frame → base_link但 SLAM Toolbox 的 base_frame 参数是 base_footprint。此时需要可以修改 SLAM Toolbox 参数ros2 param set /slam_toolbox base_frame base_link12. 实时监控所有 TF 状态ros2 run tf2_ros tf2_monitor检查两个坐标系间的具体变换ros2 run tf2_ros tf2_echo map base_link正常情况下会输出Transform from map to odom ...有数据不停刷新最后解决方案三轮小车上加雷达的TF要求map → odom SLAM 节点发Cartographer / SLAM Toolbox / GMapping odom → base_link 小车底盘驱动/里程计节点发 base_link → laser_link 静态 TF 发固定不变下面是每一段的具体操作odom → base_link 必须由底盘 / 电机驱动节点发布,OdomPublisher.py必须高频50Hzimportrclpyfromrclpy.nodeimportNodefromnav_msgs.msgimportOdometryfromgeometry_msgs.msgimportTransformStampedimporttf2_rosclassOdomPublisher(Node):def__init__(self):super().__init__(odom_publisher)self.odom_pubself.create_publisher(Odometry,/odom,10)self.tf_broadcastertf2_ros.TransformBroadcaster(self)# 定时发布 50Hzself.timerself.create_timer(0.02,self.publish_odom)# 小车位置你要从电机编码器获取self.x0.0self.y0.0self.theta0.0defpublish_odom(self):# 1. 发布 TFodom → base_linktTransformStamped()t.header.stampself.get_clock().now().to_msg()t.header.frame_idodomt.child_frame_idbase_linkt.transform.translation.xself.x t.transform.translation.yself.y t.transform.translation.z0.0t.transform.rotation.x0.0t.transform.rotation.y0.0t.transform.rotation.z0.0t.transform.rotation.w1.0self.tf_broadcaster.sendTransform(t)# 2. 发布 /odom 话题odom_msgOdometry()odom_msg.header.stampself.get_clock().now().to_msg()odom_msg.header.frame_idodomodom_msg.child_frame_idbase_linkodom_msg.pose.pose.position.xself.x odom_msg.pose.pose.position.yself.y self.odom_pub.publish(odom_msg)defmain(argsNone):rclpy.init(argsargs)nodeOdomPublisher()rclpy.spin(node)node.destroy_node()rclpy.shutdown()if__name____main__:main()base_link → laser_link 静态 TF 发固定不变ros2 run tf2_ros static_transform_publisher0.100.15000base_link laser_linkmap → odom SLAM 节点发Cartographer / SLAM Toolbox / GMappingros2 launch slam_toolbox online_async_launch.py另外这三段用通俗易懂的话来讲如下odom → base_link来源小车底盘驱动 / 电机里程计它是小车自己感觉走了多远会漂移走久了不准但高频、连续、平滑适合控制map → odom来源SLAM 算法SLAM 看雷达发现 “哎你里程计漂了”于是发布一个修正量map → odom让小车在地图上的位置稳定不飘base_link → laser_link来源静态 TF雷达装在车头前 10cm位置永远不变所以静态发布一次就行验证TF 树正常map-odom-base_link-laser_link 链路完整RViz 中 TF 随小车移动正常说明基础坐标变换链路是通的。现象佐证RViz 中出现 3 个坐标系base_link/laser_link/odom说明 TF 发布正常但 SLAM 节点的里程计输入链路有问题。

更多文章