摘要:import rclpyfrom rclpy.node import Nodefrom nav_msgs.msg import OccupancyGridclass MapSubscriber(Node):def __init__(self):# 调用父类构造
在 ROS 2 里,若要获取 /map 话题的地图数据,可借助创建一个订阅者节点来实现。下面分别给出使用 Python 和 C++ 编写的示例代码。
下面是一个使用 Python 编写的 ROS 2 节点示例,该节点用于订阅 /map 话题并打印地图的一些基本信息。
import rclpyfrom rclpy.node import Nodefrom nav_msgs.msg import OccupancyGridclass MapSubscriber(Node):def __init__(self):# 调用父类构造函数并命名节点super.__init__('map_subscriber')# 创建订阅者,订阅 /map 话题,消息类型为 OccupancyGrid,回调函数为 listener_callback,队列大小为 10self.subscription = self.create_subscription(OccupancyGrid,'/map',self.listener_callback,10)self.subscription # 防止未使用变量警告def listener_callback(self, msg):# 打印接收到的地图的分辨率self.get_logger.info('Received map with resolution: %f' % msg.info.resolution)# 打印地图的宽度和高度self.get_logger.info('Map width: %d, height: %d' % (msg.info.width, msg.info.height))# 打印地图原点的位置self.get_logger.info('Map origin: (%f, %f)' % (msg.info.origin.position.x, msg.info.origin.position.y))def main(args=None):# 初始化 ROS 2rclpy.init(args=args)# 创建 MapSubscriber 节点实例map_subscriber = MapSubscriber# 进入节点的主循环,处理回调函数rclpy.spin(map_subscriber)# 销毁节点map_subscriber.destroy_node# 关闭 ROS 2rclpy.shutdownif __name__ == '__main__':main节点初始化:在 __init__ 方法里,创建了一个名为 map_subscriber 的节点,并且订阅了 /map 话题,其消息类型为 OccupancyGrid。回调函数:listener_callback 函数会在接收到新的地图消息时被调用,此函数会打印出地图的分辨率、宽度、高度以及原点位置。主函数:main 函数对 ROS 2 进行初始化,创建节点实例,进入主循环,最后在结束时销毁节点并关闭 ROS 2。以下是使用 C++ 编写的等效节点示例:
#include "rclcpp/rclcpp.hpp"#include "nav_msgs/msg/occupancy_grid.hpp"class MapSubscriber : public rclcpp::Node{public:// 构造函数MapSubscriber : Node("map_subscriber"){// 创建订阅者,订阅 /map 话题,消息类型为 OccupancyGrid,回调函数为 std::bind(&MapSubscriber::topic_callback, this, std::placeholders::_1),队列大小为 10subscription_ = this->create_subscription("/map", 10, std::bind(&MapSubscriber::topic_callback, this, std::placeholders::_1));}private:// 回调函数void topic_callback(const nav_msgs::msg::OccupancyGrid::SharedPtr msg) const{// 打印接收到的地图的分辨率RCLCPP_INFO(this->get_logger, "Received map with resolution: %f", msg->info.resolution);// 打印地图的宽度和高度RCLCPP_INFO(this->get_logger, "Map width: %d, height: %d", msg->info.width, msg->info.height);// 打印地图原点的位置RCLCPP_INFO(this->get_logger, "Map origin: (%f, %f)", msg->info.origin.position.x, msg->info.origin.position.y);}// 订阅者对象rclcpp::Subscription::SharedPtr subscription_;};int main(int argc, char * argv){// 初始化 ROS 2rclcpp::init(argc, argv);// 创建 MapSubscriber 节点实例auto node = std::make_shared;// 进入节点的主循环,处理回调函数rclcpp::spin(node);// 关闭 ROS 2rclcpp::shutdown;return 0;}节点类定义:MapSubscriber 类继承自 rclcpp::Node,在构造函数中创建了 /map 话题的订阅者。回调函数:topic_callback 函数在接收到新的地图消息时被调用,它会打印地图的相关信息。主函数:main 函数对 ROS 2 进行初始化,创建节点实例,进入主循环,最后关闭 ROS 2。创建工作空间与功能包:要保证你的工作空间和功能包已经正确设置。编写代码:把上述代码分别保存为 map_subscriber.py 或 map_subscriber.cpp 文件。编译代码:若使用 Python,无需编译,可直接运行。若使用 C++,要在 CMakeLists.txt 中添加相应的编译规则,然后进行编译。运行节点:在终端中运行以下命令来启动节点:ros2 run
其中,
是你的功能包名称, 是可执行文件的名称。
通过以上步骤,你就能在 ROS 2 中获取 /map 话题的地图数据了。
使用ros2 命令获取使用ros2 topic info命令(可选)ros2 topic info 命令用于显示指定话题的详细信息,包括消息类型、发布者和订阅者等。若要查看 /map 话题的详细信息,可执行以下命令:
ros2 topic info /map命令执行后,会输出 /map 话题的消息类型(通常为 nav_msgs/msg/OccupancyGrid)、发布者和订阅者的节点名称等信息。
以下是一个综合使用上述命令的示例,你可以先查看 /map 话题的详细信息,再查看其发布频率,最后获取消息内容:
# 查看 /map 话题的详细信息ros2 topic info /map# 查看 /map 话题的发布频率ros2 topic hz /map# 获取 /map 话题的消息内容ros2 topic echo /map通过这些命令行工具,你可以方便地获取和分析指定话题的数据。
来源:州天看科技