ROS:通过topic发布栅格地图,让RVIZ显示

通过topic发布栅格地图,让RVIZ显示

本文主要同个一个简单的例子实现通过读地图map.pgm文件,使用topic发出后,在rviz上查看。
例子:

#include <ros/ros.h> 
#include <iostream>
#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "nav_msgs/OccupancyGrid.h"

#include <string>

int main (int argc, char** argv) 
{ 
  //初始化节点 
  ros::init(argc, argv, "serial_example_node"); 
  //声明节点句柄 
  ros::NodeHandle nh; 

  std::string file_path;
  nh.param("file_path", file_path, file_path);
  if(file_path.empty())
  {
    std::cout<<"file path is empty"<<std::endl;
  }


  ros::Publisher map_pub_ = nh.advertise<nav_msgs::OccupancyGrid>("/map_loader/map", 1, true);



  std::string grid_map_path = file_path + "map_0.pgm";

  // std::cout<<"map_path : "<<grid_map_path<<std::endl;

  //加载栅格地图
  cv::Mat grid_map = cv::imread(grid_map_path.c_str(), cv::IMREAD_GRAYSCALE);

  // std::cout<<"grid_map("<<grid_map.rows<<", "<<grid_map.cols<<std::endl;

  // nav_msgs::GetMap::Response resp;
  nav_msgs::OccupancyGrid map_msg;
  map_msg.header.frame_id = "map";
  map_msg.info.width = grid_map.cols;
  map_msg.info.height = grid_map.rows;
  map_msg.info.resolution = 0.05;

  map_msg.info.origin.position.x = 1.02321215e+01 - 25;
  map_msg.info.origin.position.y = 1.19620981e+01 - 25;

  map_msg.info.origin.orientation.w = 1.0;

  map_msg.data.resize(map_msg.info.width * map_msg.info.height);

  for(int i = 0; i < grid_map.cols; i++)
  {
    for (int j = 0; j < grid_map.rows; j++)
    {
        int value = grid_map.at<uchar>(i, j);
        if (value == 0)
        {
            map_msg.data[i * grid_map.cols + j] = 100;  // occupied
        }
        else if (value == 255)
        {
            map_msg.data[i * grid_map.cols + j] = 0;  // free
        }
        else
        {
            map_msg.data[i * grid_map.cols + j] = -1;  // unknown
        }
    }
  }

  //指定循环的频率 
  ros::Rate loop_rate(5); 
  while(ros::ok()) 
  { 
    map_pub_.publish(map_msg);

  //处理ROS的信息,比如订阅消息,并调用回调函数 
  ros::spinOnce(); 
  loop_rate.sleep(); 
  } 
} 

此处关于原点坐标
是直接写的固定值,使用SLAM建图后,在地图文件夹一般般都会存在map.yaml和map_0.pgm文件,map.yaml文件中的坐标就是pgm栅格图片的中心位置对应的坐标。如果有多张pgm图片,就可以根据map.yaml中的坐标,将图片拼接成一张大图。
map.yaml的格式如下

%YAML:1.0
---
image: "map.pgm"
resolution: 5.0000000745058060e-02
submaps: 1.
occupied_thresh: 1.9600000000000001e-01
free_thresh: 6.5000000000000002e-01
submap_0: !!opencv-matrix
   rows: 1
   cols: 2
   dt: f
   data: [ 1.02321215e+01, 1.19620981e+01 ]

本例只有一张图片,因为图片大小是像素1000X1000的。分辨率是0.05m,即一个像素表示5cm。现在有了中心点的坐标(1.02321215e+01,1.19620981e+01),求原点坐标,即使用中心点的坐标,X,Y分别减去半张图片的大小(500 * 0.05)即25m。得到的就是原点的坐标。

  map_msg.info.origin.position.x = 1.02321215e+01 - 25;
  map_msg.info.origin.position.y = 1.19620981e+01 - 25;

这个例子就没有做解析yaml的部分,直接写上了原点坐标。
launch文件也写的很简单。如下sample.launch

<?xml version="1.0" ?>
<launch>
	<node name="sample" pkg="sample" type="sample" output="screen"/>
	<param name= "file_path" value="$(find sample)/map/" type="string"/>
</launch>

这样程序写好后,就可以运行,然后发出的topic是/map_loader/map. 启动rviz,订阅这个topic就可以了。
rviz启动后,选择[add] 添加topic 选择map,即可。
在这里插入图片描述在这里插入图片描述

ROS中,rviz是一个常用的可视化工具,用于显示和分析机器人的感知数据和状态信息。在rviz中,map和submap是两个常见的概念。 map是指机器人所在环境的地图,通常是一个栅格地图。在ROS中,地图文件一般以pgm格式存储,同时还有一个对应的yaml文件,其中包含了地图的一些属性信息,如分辨率、原点坐标等。通过读取map.yaml文件,可以获取到地图的中心位置对应的坐标。如果存在多张pgm图片,可以根据map.yaml中的坐标将它们拼接成一张大图。\[1\] submap是指机器人在建图过程中生成的局部地图。在Cartographer中,submap是指一个固定大小的地图块,它包含了机器人在某个时间段内的感知数据和建图结果。在rviz中,可以通过submap_display插件来显示和管理submap。submap_display会根据接收到的submap数据更新显示,其中会将submap的位置信息赋值给submap_node,然后通过设置submap_node的位置和姿态来更新submap的显示。\[2\]\[3\] 总结起来,map是整个环境的地图,而submap是机器人在建图过程中生成的局部地图,在rviz中可以通过相应的插件来显示和管理它们。 #### 引用[.reference_title] - *1* [ROS:通过topic发布栅格地图,让RVIZ显示](https://blog.csdn.net/yangcunbiao/article/details/131268403)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [cartographer基于grpc、rosrviz地图显示流程](https://blog.csdn.net/windxf/article/details/108883957)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [cartographer_rviz submap地图绘制](https://blog.csdn.net/windxf/article/details/109220665)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值