【cartographer_ros】六: 发布和订阅路标landmark信息
上一节介绍了陀螺仪Imu传感数据的订阅和发布。
本节会介绍路标Landmark数据的发布和订阅。Landmark在cartographer中作为定位的修正补充,避免定位丢失。
这里着重解释一下Landmark,它与Scan,Odom,Imu数据不同,并不是直接的传感数据。它是地图上的特征点,通常是易被识别的物体。
在cartographer中,通常是用反光柱或者二维码做landmark,实际上反光柱用的更多,因为反光柱同样可以使用激光雷达识别,不需要添加多的传感器。
对于用反光板构建landmark,推荐slam大佬峰哥的博文:
使用2个反光柱作为landmark
使用3个反光柱作为landmark
对于用二维码作用landmark,这里同样推荐峰哥的博文:
使用二维码作为landmark
当然,在学习构建landmark之前,先看看Landmark的结构及如何订阅和发布landmark。
目录
1:cartographer_ros_msgs/LandmarkList消息类型
1:cartographer_ros_msgs/LandmarkList消息类型
在终端查看消息数据结构:
rosmsg show cartographer_ros_msgs/LandmarkList
Landmark消息类型数据结构如下:
std_msgs/Header header
uint32 seq
time stamp
string frame_id
cartographer_ros_msgs/LandmarkEntry[] landmarks
string id
geometry_msgs/Pose tracking_from_landmark_transform
geometry_msgs/Point position
float64 x
float64 y
float64 z
geometry_msgs/Quaternion orientation
float64 x
float64 y
float64 z
float64 w
float64 translation_weight
float64 rotation_weight
LandmarkList中的landmarks是LandmarkEntry合集,LandmarkEntry对应的是单个路标的位置和姿势,所以LandmarkList其实是一个或多个路标的信息。
2:发布LandmarkList消息
#include <ros/ros.h>
#include <cartographer_ros_msgs/LandmarkList.h>
#include <cartographer_ros_msgs/LandmarkEntry.h>
int main(int argc, char** argv){
ros::init(argc, argv, "landmark_publisher");
ros::NodeHandle n;
ros::Publisher landmark_pub = n.advertise<cartographer_ros_msgs::LandmarkList>("landmark", 50);
ros::Rate r(1.0);
while(n.ok()){
cartographer_ros_msgs::LandmarkList landmarkList;
landmarkList.header.stamp = ros::Time::now();
landmarkList.header.frame_id = "base_link";
landmarkList.landmarks.resize(10);
for(int i = 0; i < 10; i++)
{
landmarkList.landmarks[i].id = std::to_string(i);
landmarkList.landmarks[i].tracking_from_landmark_transform.position.x = 1*i;
landmarkList.landmarks[i].tracking_from_landmark_transform.position.y = 2*i;
landmarkList.landmarks[i].tracking_from_landmark_transform.position.z = 3*i;
landmarkList.landmarks[i].tracking_from_landmark_transform.orientation.w = 1;
landmarkList.landmarks[i].tracking_from_landmark_transform.orientation.x = 0;
landmarkList.landmarks[i].tracking_from_landmark_transform.orientation.y = 0;
landmarkList.landmarks[i].tracking_from_landmark_transform.orientation.z = 0;
landmarkList.landmarks[i].translation_weight = 10;
landmarkList.landmarks[i].rotation_weight = 10;
}
landmark_pub.publish(landmarkList);
r.sleep();
}
}
值得注意的是,在真实的数据中,有多个反光柱时landmarks.id应该要是独一无二的,能通过id找到确定路标的。
所以如何识别和确定id是一个问题,通常辅助其他的反光柱构建特征三角形来识别和确定id。具体的可以参照其他资料,有机会作者会对此展开补充。
3:订阅Landmark消息
(1) 通过rosbag订阅
rostopic echo /landmark
(2) 通过rviz查看
打开rviz
rosrun rviz rviz
同时需要在cartographer配置文件中设置use_landmarks= true,并运行cartographer节点。
因为rviz无法接收显示cartographer_ros_msgs/LandmarkList,但是可以查看cartographer接收到landmark话题消息后发布的landmrk_pose_list。
Fixed Frame修改为base_link,添加Landmark并将Topic设为/landmrk_pose_list
(3) 编写程序打印
#include "ros/ros.h"
#include "cartographer_ros_msgs/LandmarkList.h"
#include "cartographer_ros_msgs/LandmarkEntry.h"
void LandmarkCallback(const cartographer_ros_msgs::LandmarkList::ConstPtr &msg)
{
ROS_INFO("Landmark Size: %d", msg->landmarks.size());
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");
ros::NodeHandle node;
ros::Subscriber sublandmark = node.subscribe("landmark", 1000, LandmarkCallback);
ros::spin();
return 0;
}
cartographer算法运行所需要的传感器数据的结束到此就告一段落了,在了解完数据的发布和订阅之后,接着来看怎样在cartographer算法中融入和配置这些数据。
【完】
下一节会介绍cartographer的主要配置参数。
【cartographer_ros】六: 发布和订阅路标landmark信息的更多相关文章
- 【cartographer_ros】五: 发布和订阅陀螺仪Imu信息
上一节介绍了里程计Odometry传感数据的订阅和发布. 本节会介绍陀螺仪Imu数据的发布和订阅.陀螺仪在cartographer中主要用于前端位置预估和后端优化. 目录 1:sensor_msgs/ ...
- 【cartogarpher_ros】三: 发布和订阅雷达scan信息
上一节介绍和测试了cartographer的官方demo. 本节会编写ros系统中,最常用的激光雷达LaserScan传感数据的订阅和发布,方便在cartographer中加入自己的数据进行建图与定位 ...
- 【cartographer_ros】四: 发布和订阅里程计odom信息
上一节介绍了激光雷达Scan传感数据的订阅和发布. 本节会介绍里程计Odom数据的发布和订阅.里程计在cartographer中主要用于前端位置预估和后端优化. 官方文档: http://wiki.r ...
- EasyNetQ使用(六)【多态发布和订阅,消息版本控制】
你能够订阅一个接口,然后发布基于这个接口的实现. 让我们看下一个示例.我有一个接口IAnimal和两个实现Cat和Dog: public interface IAnimal { string Name ...
- Redis的高级应用-事务处理、持久化、发布与订阅消息、虚拟内存使用
三.事务处理 Redis的事务处理比较简单.只能保证client发起的事务中的命令可以连续的执行,而且不会插入其他的client命令,当一个client在连接 中发出multi命令时,这个连接就进入一 ...
- redis 发布和订阅实现
参考文献 15天玩转redis -- 第九篇 发布/订阅模式 <Redis设计与实现> 命令简介 在redis用户手册中,跟发布订阅相关的命令有如下的六个: PSUBSCRIBE PUBL ...
- (转)SqlServer 数据库同步的两种方式 (发布、订阅),主从数据库之间的同步
最近在琢磨主从数据库之间的同步,公司正好也需要,在园子里找了一下,看到这篇博文比较详细,比较简单,本人亲自按步骤来过,现在分享给大家. 在这里要提醒大家的是(为了更好的理解,以下是本人自己理解,如有错 ...
- (原)3.2 Zookeeper应用 - 数据的发布与订阅
本文为原创文章,转载请注明出处,谢谢 数据的发布与订阅 1.应用 服务端监听数据改变,客户端创建/更新节点数据,客户端提供数据,服务端处理 2.原理 客户端监控节点数据改变事件(例如配置信息,下图的c ...
- MSSQLSERVER之发布-分发-订阅
一.环境 发布服务器 O S: Windows servier 2003 64位 Soft: Microsoft SqlServer 2008 R2 I P: 192.168.3.70 HOST-NA ...
随机推荐
- 二次封装这几个 element-ui 组件后,大大减少了我 CRUD 的时间
element-ui 因其组件丰富.可拓展性强.文档详细等优点成为 Vue 最火的第三方 UI 框架.element-ui 其本身就针对后台系统设计了很多实用的组件,基本上满足了平时的开发需求. 既然 ...
- oauth协议原理
oauth协议关系图(如获取微信用户信息): oauth一般授权步骤:
- Linux-centos8实现私有CA和证书申请
创建CA相关目录,centos8不存在这些目录,需手动建立 [root@centos8-liyj ~]#mkdir -pv /etc/pki/CA/{certs,cr1,newcerts,privat ...
- 【机器学习基础】无监督学习(3)——AutoEncoder
前面主要回顾了无监督学习中的三种降维方法,本节主要学习另一种无监督学习AutoEncoder,这个方法在无监督学习领域应用比较广泛,尤其是其思想比较通用. AutoEncoder 0.AutoEnco ...
- 一次 HTTP 请求就需要一次 TCP 连接吗?
一次 HTTP 请求就需要一次 TCP 连接吗? 本文写于 2021 年 2 月 9 日 太长不看版本:短连接需要,长连接不需要. 一次 HTTP 请求就需要一次 TCP 连接吗? TCP 的连接与断 ...
- SQL语句中LEFT JOIN ON WHERE和LEFT JOIN ON AND的区别
先上代码: declare @tb table (name varchar(10),sex int) declare @tb2 table (name varchar(10),age int) ins ...
- 记一次Tomcat卡死在 Deploying web application 步骤的问题
公司有一个历史的遗留项目是传统的MVC架构的前后不分离的项目,一开始使用JDK1.7写的,后来前一阵老板说想在这个远古项目上加点功能,顺带换换皮,于是乎一帮程序员们就用JDK1.8重新翻新了一遍项目顺 ...
- Netty是什么,Netty为什么速度这么快,线程模型分析
哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 书接上回,现在下着大雨看来是去 ...
- 《HALCON数字图像处理》第一、二章笔记
目录 第一章 绪论 1.1 图像和图像处理 1.1.1 图像 1.1.2 数字图像 1.1.3 图像处理及其发展过程 1.2 数字图像处理的步骤和方法 1.3 数字图像处理系统的硬件组成 1.4 数字 ...
- 用C语言实现井字棋(人人/AI人机)--完结版
目录 用C语言实现井字棋(人人/AI人机)--完结版 BUG与优化3: 1. 修改了step的计算方法,每个玩家玩完就加一次step 2. 改变了电脑下棋的逻辑,每个玩家玩完之后都跳过这次循环 源码: ...