1. 程式人生 > >ROS——SLAM實時更新顯示柵格地圖之nav_msgs::OccupancyGrid

ROS——SLAM實時更新顯示柵格地圖之nav_msgs::OccupancyGrid

文章目錄


效果圖

  廢話不說,直接上最終效果圖~看完圖你應該就知道是不是你想要的東東。這是對Gazebo其中一個部分場景的無人機SLAM效果圖。黑色塊為障礙物,顏色較深的灰色塊為危險區,顏色再淺一點的是可行區域,最淺的是未知區域(最外圍的區域);
Rviz實時SLAM重建效果圖如下:

Gazebo場景圖如下:


OccupancyGrid概述

官方資料型別解釋

如下:

nav_msgs/OccupancyGrid Message
File: nav_msgs/OccupancyGrid.msg
Raw Message Definition

# This represents a 2-D grid map, in which each cell represents the probability of
# occupancy.

Header header 

#MetaData for the map
MapMetaData info

# The map data, in row-major order, starting with (0,0).  Occupancy
# probabilities are in the range [0,100]. Unknown is -1. int8[] data

訊息定義格式如下:

std_msgs/Header header
nav_msgs/MapMetaData info
int8[] data

OccupancyGrid使用注意事項

1.向Rviz傳送的資料中一定要包含frame_id

map.header.frame_id="grid";

2.柵格地圖初始化大小為

map.info.width      = 20;           // 寬
map.info.height     =
20; // 高

3.柵格地圖解析度對應柵格地圖中一小格的長和寬

map.info.resolution = 0.5;

4.柵格地圖中每一個小格的座標對應一位陣列中的一個數據。
例如:
實際地圖中某點座標為(x,y),對應柵格地圖中座標為[x*map.info.width+y]

5.柵格地圖中每個小格的顏色代表的是該格被佔用的概率,顏色越深表明被佔用率越高,也就是有更高的可能是障礙物/建築物。為什麼是概率那,因為建立柵格地圖要依賴於GPS或其他導航系統,導航系統都是有誤差的,哪怕精度再高,因此基於這些位置資訊建立出來的柵格地圖存在一定的不準確度,就使用概率來表示。概率的範圍是[0,100],如果是未知區域可以將該位置的概率設定為-1


建立工程

1.建立工程所在資料夾

mkdir grid
cd grid
mkdir src

2.建立ROS工程的grid

catkin_create_pkg grid std_msgs rospy roscpp

3.在建立好的ROS工程內建立新的gridMap.cpp檔案,並新增如下程式

#include "ros/ros.h"
#include "sensor_msgs/LaserScan.h"
#include "nav_msgs/OccupancyGrid.h"

int main(int argc, char * argv[]) {

  ros::init(argc, argv, "gridMap");

  ros::NodeHandle nh;
  ros::NodeHandle nh_private("~");

  ros::Publisher pub = nh.advertise<nav_msgs::OccupancyGrid>("/gridMap", 1);
  nav_msgs::OccupancyGrid map;

  map.header.frame_id="grid";
  map.header.stamp = ros::Time::now(); 
  map.info.resolution = 0.5;         // float32
  map.info.width      = 20;           // uint32
  map.info.height     = 20;           // uint32
  
  int p[map.info.width*map.info.height] = {-1};   // [0,100]
  p[10] = 100;
  std::vector<signed char> a(p, p+400);
  map.data = a;

  while (ros::ok())
  {
      pub.publish(map);
  }

  ros::shutdown();
  return 0;
}

4.修改CMakeLists.txt檔案,在檔案中新增如下程式

add_executable(gridMap
  src/gridMap.cpp
)
add_dependencies(gridMap ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(gridMap
  ${catkin_LIBRARIES}
)

5.編譯工程

catkin_make

6.執行工程
6.1.首先執行

roscore

6.2.執行新建的結點

source devel/setup.bash
rosrun grid gridMap

在Rviz中實時現實柵格地圖

1.開啟Rviz

rosrun rviz rviz
2.建立柵格地圖 點選左下角新增按鈕`Add`,在開啟的`Create visualization`欄中選擇`Map`,並點選`OK`鍵確認。 3.開啟`Map`下拉列表中的屬性資訊,在`Topic`話題後面輸入/選擇`/gridMap`話題,即可看到刪咯地圖在Rviz中現實的結果。此時雖然會現實柵格地圖,但是會出現Error提示,因此修改`Global Option`屬性中的`Fixed Frame`對應程式中的`grid`,這時錯誤提示消失,正常顯示刪咯地圖。 **註釋** `Global Option`屬性中的`Fixed Frame`對應程式中向Rviz釋出訊息的訊息頭中的`frame_id`,即 ```c map.header.frame_id="grid"; ``` `Map`屬性中的`Topic`對應程式中向Rviz釋出訊息的話題名,即 ```c ros::Publisher pub = nh.advertise("/gridMap", 1); ```

結束語

至此已經可以在Rviz中顯示柵格地圖,快去實現你自己的SLAM吧~