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,即可。
在这里插入图片描述在这里插入图片描述

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用rviz中的ArrowMarker或VectorMarker实现向量的显示。首先,您需要在rviz中创建一个可视化的Topic,例如"/visualization_marker",并将其类型设置为marker_array。然后,您可以使用以下代码示例在ROS发布ArrowMarker或VectorMarker消息,并将其发布到相应的Topic中,从而在rviz显示向量: ```python import rospy from visualization_msgs.msg import Marker, MarkerArray from geometry_msgs.msg import Vector3 rospy.init_node('vector_example') # Create marker publisher marker_pub = rospy.Publisher('/visualization_marker', MarkerArray, queue_size=10) # Create arrow marker arrow_marker = Marker() arrow_marker.type = Marker.ARROW arrow_marker.header.frame_id = "map" arrow_marker.header.stamp = rospy.Time.now() arrow_marker.scale.x = 0.1 arrow_marker.scale.y = 0.2 arrow_marker.scale.z = 0 arrow_marker.color.a = 1.0 arrow_marker.color.r = 1.0 arrow_marker.color.g = 0.0 arrow_marker.color.b = 0.0 arrow_marker.pose.orientation.w = 1.0 # Create vector message v = Vector3(1.0, 0.0, 0.0) # Create marker array message marker_array = MarkerArray() arrow_marker.points = [v] marker_array.markers.append(arrow_marker) # Publish marker array marker_pub.publish(marker_array) rospy.spin() ``` 在这个例子中,我们创建了一个ArrowMarker,并在其中定义了其尺寸、颜色和方向。然后,我们创建了一个Vector3消息,并将其添加到ArrowMarker的顶点列表中。最后,我们将ArrowMarker添加到MarkerArray消息中,并将其发布到可视化Topic中。当我们运行此代码时,我们将在rviz中看到一个红色箭头,表示指向x轴正方向的向量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值