ROS中slam_gmapping、map_server源码解读及其librviz的使用

2023-05-16

 SLAM全称simultaneous localization and mapping,即实时定位与地图构建。也就是说导航离不开地图,目前常用的地图构建方法有三种:

1、gmapping,一种基于粒子滤波的算法,依赖里程计数据。ROS中的slam_gmapping包也是调用了openslam_gmapping开源算法。openslam_gmapping的介绍及其源码可在http://wiki.ros.org/openslam_gmapping?distro=indigo和https://github.com/ros-perception/openslam_gmapping上看到。

2、hector slam,不需要用到里程计,对于雷达帧率要求很高(40Hz)。关于hector slam的介绍可查阅网站http://wiki.ros.org/hector_slam和https://github.com/tu-darmstadt-ros-pkg/hector_slam(源码)。

3、cartographer,累计误差较小,由谷歌推出,效果还是挺炫的。其介绍和源码的相关网站为http://wiki.ros.org/cartographer和https://github.com/googlecartographer/cartographer。

关于这三种方法,具体可查看博文《Gmapping、hector、Cartographer三种激光SLAM算法简单对比》。

 

下面言归正传说说ros中slam_gmapping包和map_server包的作用。

一、slam_gmapping和map_server

这两个包是在建图时是用得最多的。

1、slam_gmapping

前面也说过,slam_gmapping包也是依赖开源openslam_gmapping库。下载openslam_gmapping后编译会生成几个动态库,libgridfastslam.so,libscanmatcher.so,libsensor_base.so,libsensor_odometry.so,libsensor_range.so和libutils.so,源码没有仔细研究,不过看名字也大概可以知道它们的作用。

在slma_gmapping包中编译后会生成好几个节点,不过真正需要调用的建图节点的主要实现在slam_gmapping.cpp中,通过roslaunch slam_gmapping slam_gmapping.launch或者rosrun gmapping slam_gmapping scan:=scan启动,开始扫图。

首先是初始化,载入或者配置参数。

然后调用startLiveSlam函数开启建图模式,在这个函数中会发布三个话题,/enropy(机器人姿态分布熵的估计),/map(建图过程中的数据,用占有网格数据描述,其值在0~255之间),/map_metadta(地图的描述消息);会发布一个服务,/dynamic_map,也是为了获取地图数据;会订阅激光数据和tf坐标转换后的数据,还用到了message_filters方法,也是为了加快数据传输效率。此外,还开启了一个线程,用于不断广播map和odom之间的坐标变换。

其次的关键就是对获取的点云scan数据进行处理,这个在回调函数laserCallback中实现。一旦第一次获取到scan数据,会调用initMapper函数形成一个初始的地图形状,这个函数里面也是进行了大量tf变换,然后通过getOdomPose函数获取机器人初始位置,正常情况下该函数只会执行一次,再往后获取到的scan数据则由addScan函数处理了。addScan函数中会先得到里程计数据,然后处理scan数据。最后更新地图数据,由updateMap函数完成,并调用computePoseEntropy函数计算机器人位置分布熵,同时发布map和map_metadata消息。

slam_gmapping包的主要工作就这些,就是将数据处理为了在ros通讯机制下的,其核心算法还是在openslam_gmapping里面实现的。

2、map_server

map_server的功能就是地图服务器。编译map_server后会生成map_server_image_loader动态库,这个用于处理pgm格式的图片,其依赖了SDL库;还会生成map_server和map_saver节点。

map_server节点的源代码很容易看懂,主要就是为了加载pgm格式的地图,用yaml文件描述的,同时发布map_metadata和map话题,以及static_map服务,其目的都是为了方便其他节点获取到地图数据。指令为rosrun map_server map_server mymap.yaml。

map_saver的作用就是为了将slam_gmapping建图数据保存下来,主要就是订阅map消息。rosrun map_server map_saver -f mymap。

具体操作及其参数说明可参见http://wiki.ros.org/map_server。

二、librviz的使用

前面的操作都是在指令下进行的,如果想看到建图时的实时效果可通过rviz软件查看。但是如果想自己开发软件,可使用librviz。正如官网所说,rviz不仅仅是一个可视化工具,还是一个库,可被其他程序所调用。

官网给的例子还是挺简单的。此外,rviz用的qt4库,至少ros indigo版本是的。

加载rviz显示的关键代码如下:

rviz::RenderPanel * render_panel_;
render_panel_ = new rviz::RenderPanel;
rviz::VisualizationManager *manager_;
manager_ = new rviz::VisualizationManager(render_panel_);
render_panel_->initialize(manager_->getSceneManager(), manager_);
manager_->initialize();
manager_->startUpdate();

rviz::Display *map = manager_->createDisplay("rviz/Map", "adjustable map", true);
map->subProp("Topic")->setValue("/map");

首先是声明一个rviz的RenderPanel,这个面板类最终也是继承了QWidget,然后声明一个可视化管理类,继承于QObject,再初始化,VisualizationManager就可以开始不断更新了。上面代码段显示了如何加载地图,也是通过创建一个显示(createDisplay),然后添加topic值。

结合官方给的例子,可以自写一个调用librviz的小程序,运行效果如下:

 

该小程序可以在https://github.com/WelinLee/ROS_QT_GUI中的vizlib_test包中找到。

 

Enjoy!

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS中slam_gmapping、map_server源码解读及其librviz的使用 的相关文章

  • Node.js 应用程序在 Heroku 上不断崩溃,并给出错误 Boot timeout

    我正在开发一个示例 node js 应用程序 它在本地运行良好 node index js 但是 当我将其推送到 Heroku 实例时 它崩溃并出现以下错误 2017 10 23T06 08 07 000000 00 00 app api
  • 同一服务器上的两个 Laravel 项目导致冲突

    我在同一台服务器上有两个 Laravel 5 1 项目 在单个项目上操作不会给我带来任何麻烦 但是如果我在两个浏览器选项卡上打开两个项目并在它们之间交替 我会收到 服务器遇到内部错误或配置错误 无法完成您的请求 进行了研究 发现服务器正在记
  • 如何使用 Koa 提供静态文件?

    我想在我的项目中实现通用链接 并且需要通过 Koa 提供 json 这是一个名为苹果应用程序站点关联 我的文件位于 assets apple app site association apple app site association f
  • 如何在同一域中托管我的 API 和 Web 应用程序?

    我有一个Rails API 和一个Web 应用程序 使用express 彼此完全分开且独立 我想知道的是 我必须单独部署它们吗 如果我这样做 我怎样才能使我的 api 处于mysite com api和网络应用程序mysite com 我见
  • Meteor 服务器 Websocket

    我正在寻找在 Meteor 服务器 而不是客户端 上创建一个 websocket 以连接到外部网站 我知道我要访问的 URL 以及期望的数据 但我不清楚如何准确地创建 websocket 本身 我所做的所有搜索都为我提供了客户端解决方案 但
  • 用于发送字符串数据的简单 rpyc 客户端和服务器

    我正在使用 rpyc 在 python 中编写一个程序 我的目标是创建一个简单的服务器 它接受来自客户端的数据字节 字符串 我对 python 和 rpyc 都很陌生 这是我的 server py 代码 from rpyc utils se
  • 如何在 Laravel 中为 20 分钟后的每条新记录制定调度程序任务?

    我有一个停车系统 我使用 Angular 6 Laravel 作为后端 但我有一个具体问题 我不知道正确的方法 公园有两个图腾 它们向我的服务器发送一个条目 只有当客户从出口走出图腾并进入付款区时 我才会检查客户是否无效 这是我的代码 当他
  • websphere - CWWKE0054E 错误无法打开文件

    我正在尝试从命令行运行 websphere liberty profile 服务器 我正在按照此处所述的步骤进行操作 https developer ibm com wasdev downloads liberty profile usin
  • 服务器显示文本而不是 HTML

    我正在尝试创建一个 C 服务器 它将接受输入并能够通过 html 格式将它们返回给用户 其中服务器充当用户界面 我当前的问题似乎无法弄清楚为什么 C 服务器在 localhost 3838 处将 HTML 代码以文本形式吐出 而不是将其显示
  • ReactJS (create-react-app) 在端口 80 上运行 [重复]

    这个问题在这里已经有答案了 有人可以解释如何在端口 80 上运行我的reactJS应用程序 而不指定端口 目前它可以在 www mydomain com 3001 上运行 但我希望当我访问 www mydomain com 时它是可见的 我
  • new URL() - WHATWG URL API

    我正在摆弄节点 并试图获取 URL 类的实例 因为这些方便的属性 喜欢 const URL require url http createServer request response gt let uri new URL request
  • 如何使 nixos 上的 Zabbix 在本地网络中可用

    我的笔记本电脑和我的 nixos 服务器 主机名 nixos 都连接到我的路由器 fritz box 我可以通过 ping 访问 rooter ping nixos fritz box 和 ssh ssh email protected c
  • nginx 服务器中不允许方法 405 错误

    我们的反应应用程序在我们的本地机器上正常工作 但我们将其延迟到更高的环境中 它不起作用 它发送405 Method not allowed error 页面正在加载 每当我们要求时submit form这个问题来了 下面是我的nginx c
  • 当 URL 可在浏览器中访问时,SSH Curl 不起作用

    This post is linked with another post of mine still unsolved Laravel 作曲家更新 连接被拒绝 https stackoverflow com questions 52404
  • PHP 扩展 mysqli 和 nd_mysqli 之间的区别[重复]

    这个问题在这里已经有答案了 Mysqli 准备好的语句 如下所示 在以下情况下会抛出以下错误 get result 叫做 stmt connection gt prepare select column from table where i
  • 在云服务器中运行 python 脚本的最简单方法是什么?

    我有一个网络爬行 python 脚本 需要几个小时才能完成 并且无法在我的本地计算机上完整运行 有没有一种方便的方法可以将其部署到简单的 Web 服务器 该脚本基本上将网页下载到文本文件中 如何最好地实现这一点 谢谢 既然你说性能是一个问题
  • jinja2.exceptions.TemplateNotFound:index.html

    我尝试使用 Flask 打开 index html run py from app import app app run debug True init py from flask import Flask app Flask name f
  • 如何关闭 Grizzly 日志记录?

    如何关闭 Grizzly 的日志记录 我想关闭以下日志记录 Okt 18 2018 8 42 24 AM org glassfish grizzly http server NetworkListener start INFORMATION
  • 套接字:监听积压并接受

    listen sock backlog 在我看来 参数backlog限制连接数量 这是我的测试代码 server initialize the sockaddr of server server sin family AF INET ser
  • IIS 如何识别请求的是哪个站点?

    如果我在一台服务器上托管多个站点 并且 dns 服务器将不同的域名解析到同一地址 这是服务器的名称 那么 IIS 如何知道最终请求的是哪个站点 因此 客户端输入我的 1 站点地址 gt myrandomsite mydomain com 然

随机推荐