提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、栅格地图
栅格地图的使用:
nav_msgs::OccupancyGrid中的/map话题
在nav_msgs::OccupancyGrid消息包中栅格地图是以数组的形式表达的;
可以在index.ros.org官网搜索map_server节点查看对应信息
关于地图的描述:
栅格地图里的数据都是int8类型的数据,按照行优先顺序,从栅格矩阵的(0,0)位置开始排列(栅格地图的左下角为起点);
栅格里的障碍物占据值的取值是从0到100,如果栅格里的障碍物状况未知,则栅格数值为-1;
地图的相关信息内容:
time_map load_time地图的加载时间
float32 resolution地图分辨率
uint32 width地图的长度
uint32 height地图的高度
geometry_msgs/Pose origin地图的原点位置
二、发布栅格地图
发布2X4(两行四列)的地图:
1.构建一个软件包map_pkg,依赖项里加上nav_msgs;
cd catkin_ws/src/
catkin_create_pkg map_pkg rospy roscpp nav_msgs
2.在map_pkg里创建map_pub_node节点;
3.在节点中发布话题/map,消息类型为nav_msgs::OccupancyGrid;
4.构建一个地图消息包nav_OccupancyGrid,并对其赋值;
5.将地图消息包发送到话题/map;
#include <ros/ros.h>
#include <nav_msgs/OccupancyGrid.h>
int main(int argc, char *argv[])
{
ros::init(argc, argv, "map_pub_node");
ros::NodeHandle nh;
ros::Publisher map_pub = nh.advertise<nav_msgs::OccupancyGrid>("/map", 10);
ros::Rate r(1); // publish at 10 Hz
while (ros::ok())
{
nav_msgs::OccupancyGrid map;
map.header.frame_id = "map";//坐标系id
map.header.stamp = ros::Time::now(); // current time
map.info.resolution = 1.0; // 地图分辨率
map.info.width = 4; // number of cells in the x direction
map.info.height = 2; // number of cells in the y direction
map.data.resize(map.info.width * map.info.height); // allocate memory for map data
map.data[0] = 100;
map.data[1] = 100; // cell 1 is occupied
map.data[2] = 0; // cell 2 is free
map.data[3] = 0;
map.data[4] = -1; // cell 3 is unknown
// map.info.origin.position.x = 0;
// map.info.origin.position.y = 0;
// map.info.origin.orientation.w = 1.0;
map_pub.publish(map);
r.sleep();
}
return 0;
}
6.设置编译规则;
# add_executable(${
PROJECT_NAME}_node src/map_pkg_node.cpp)
# target_link_libraries(${
PROJECT_NAME}_node
# ${
catkin_LIBRARIES}
# )
复制到CmakeLists.txt文件末尾,修改如下:
add_executable(map_pub_node src/map_pub_node.cpp)
target_link_libraries(map_pub_node
${
catkin_LIBRARIES}
)
7.编译运行节点;
cd catkin_ws/
catkin_make
启动ros
roscore
运行节点
rosrun map_pkg map_pub_node
运行rviz
rviz
8.启动RViz,订阅话题/map,显示地图;
确定地图原点:
1.在rviz界面添加一个坐标系标识
ADD-Axes
标识的位置即世界坐标系的原点
2.添加地图显示
ADD-Map
将地图的话题设置成本章发布的话题/map
地图的标号如下:
[4] [5] [6] [7]
[0] [1] [2] [3]
对照下列赋值(100表示有障碍物,-1表示未知,0表示空白区域)
map.data[0] = 100;
map.data[1] = 100; // cell 1 is occupied
map.data[2] = 0; // cell 2 is free
map.data[3] = 0;
map.data[4] = -1; // cell 3 is unknown
三、初识SLAM
激光雷达发布/scan话题,SLAM节点(hector_mapping)只需要订阅该话题即可获取雷达测距数值,之后SLAM节点发布地图数据话题/map,使用rviz即可显示地图的形状。
关于hector_mapping
在index.ros.org官网可以搜索查看具体信息;
其订阅了如下话题:
/scan (sensor_msgs/LaserScan)
/syscommand (std_msgs/String,主要用来接收重新建图的指令)
其发布了如下话题:
/map_metadata(nav_msgs/String)地图数据描述信息:
time map_load_time地图加载时间
float32 resolution地图分辨率
uint32 width、height地图宽度、地图高度
geometry_msgs/Pose origin
/map(nav_msgs/OccupancyGrid)栅格地图数据
/slam_out_pose(geometry_msgs/PoseStamped)原始机器人定位信息
/poseupdate(geometry_msgs/PoseWithCovarianceStamped)矫正后的机器人定位信息
体验hector_mapping
安装hector(前面安装过wpr_simulation,默认已经安装好了hecor,如果没有就执行下列指令)
sudo apt install ros-noetic-hector-mapping
运行slam仿真环境
roslaunch wpr_simulation wpb_stage_slam.launch
运行SLAM节点(软件包名称和节点名称都是hector_mapping)
rosrun hector_mapping hector_mapping
打开rviz
直接输入rviz也行
rosrun rviz rviz
在rviz中添加机器人模型
ADD-RobotModel
在rviz中添加激光雷达的扫描测距点
此外激光雷达需要发布/scan话题
测距不明显,调节测距点大小
在rviz界面添加地图
ADD-Map
利用rqt_robot_steering工具让机器人动起来,观测地图构建过程;
rosrun rqt_robot_steering rqt_robot_steering
launch文件的使用
为了方便后续的调试,这里可以编写launch文件:
cd catkin_ws/src/
catkin_create_pkg slam_pkg roscpp rospy std_msgs
打开vscode,在上述slam_pkg文件中创建launch文件夹
在launch文件夹中新建一个文件:hector.launch
将下列指令按照.launch文件的语法写入hector.launch
roslaunch wpr_simulation wpb_stage_slam.launch
rosrun hector_mapping hector_mapping
rosrun rviz rviz
rosrun rqt_robot_steering rqt_robot_steering
这里可以使用rospack指令获取软件包的完整路径
<launch>
<include file="$(find wpr_simulation)/launch/wpb_stage_slam.launch"/>
<node pkg="hector_mapping" type="hector_mapping" name="hector_mapping"/>
<node pkg="rviz" type="rviz" name="rviz"/>
<node pkg="rqt_robot_steering" type="rqt_robot_steering" name="rqt_robot_steering"/>
</launch>
(编译后)启用上述节点
roslaunch slam_pkg hector.launch
rviz配置的保存与调用
rivz每次配置都比较麻烦,可以将rviz的显示设置保存为文件;
点击左上角的File-Save Config As
将配置文件保存到上述新建的slam_pkg里(单独新建一个rviz文件存放配置)
文件名称取:slam.rviz
检查配置文件是否正确
关闭rviz,输入指令
rosrun rviz rviz -d /home/robot/catkin_ws/src/slam_pkg/rviz/slam.rviz
将配置文件写入launch文件中
<launch>
<include file="$(find wpr_simulation)/launch/wpb_stage_slam.launch"/>
<node pkg="hector_mapping" type="hector_mapping" name="hector_mapping"/>
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find slam_pkg)/rviz/slam.rviz"/>
<node pkg="rqt_robot_steering" type="rqt_robot_steering" name="rqt_robot_steering"/>
</launch>
运行
roslaunch slam_pkg hector.launch
发现配置成功倒入进来了
如果是在实体机器人上运行Hector_Mapping,只需要将
<include file="$(find wpr_simulation)/launch/wpb_stage_slam.launch"/>
其中的wpb_stage_slam替换成启动实体机器人激光雷达和底盘控制的launch文件即可;
或者只启动激光雷达推动机器人建图;
总结
简单介绍了栅格地图,发布了简单的栅格地图,简单体验了SLAM的建图功能。