【cartographer_ros】四: 发布和订阅里程计odom信息

2023-11-09

上一节介绍了激光雷达Scan传感数据的订阅和发布。

 

本节会介绍里程计Odom数据的发布和订阅。里程计在cartographer中主要用于前端位置预估和后端优化。

官方文档:
http://wiki.ros.org/navigation/Tutorials/RobotSetup/Odom


目录

1:nav_msgs/Odometry消息类型

2:发布Odometry消息

3:订阅Odometry消息


1:nav_msgs/Odometry消息类型

在终端查看消息数据结构:

rosmsg show nav_msgs/Odometry

Odometry消息类型数据结构如下:

Header header
string child_frame_id
geometry_msgs/PoseWithCovariance pose
geometry_msgs/TwistWithCovariance twist

其中pose是位置数据,twist是速度数据。
因为还有其他的数据结构,这里展开一下,更加清晰一点:


2:发布Odometry消息

定义了在一个圆圈中行驶的假机器人的里程计数据用来进行发布

#include <ros/ros.h>
#include <tf/transform_broadcaster.h>
#include <nav_msgs/Odometry.h>

int main(int argc, char** argv){
  ros::init(argc, argv, "odometry_publisher");

  //创建一个ros::Publisher和一个tf::TransformBroadcaster以便能够分别使用 ROS 和 tf 发送消息。
  ros::NodeHandle n;
  ros::Publisher odom_pub = n.advertise<nav_msgs::Odometry>("odom", 50);
  tf::TransformBroadcaster odom_broadcaster;

  double x = 0.0;
  double y = 0.0;
  double th = 0.0;

  double vx = 0.1;
  double vy = -0.1;
  double vth = 0.1;

  ros::Time current_time, last_time;
  current_time = ros::Time::now();
  last_time = ros::Time::now();

  ros::Rate r(1.0);
  while(n.ok()){

    ros::spinOnce();            
    current_time = ros::Time::now();

    //根据设置的速度更新里程信息
    double dt = (current_time - last_time).toSec();
    double delta_x = (vx * cos(th) - vy * sin(th)) * dt;
    double delta_y = (vx * sin(th) + vy * cos(th)) * dt;
    double delta_th = vth * dt;

    x += delta_x;
    y += delta_y;
    th += delta_th;

    geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(th);

    //创建一个TransformStamped消息,通过 tf发布从“odom”到“base_link”的转换
    geometry_msgs::TransformStamped odom_trans;
    odom_trans.header.stamp = current_time;
    odom_trans.header.frame_id = "odom";
    odom_trans.child_frame_id = "base_link";

    odom_trans.transform.translation.x = x;
    odom_trans.transform.translation.y = y;
    odom_trans.transform.translation.z = 0.0;
    odom_trans.transform.rotation = odom_quat;

    odom_broadcaster.sendTransform(odom_trans);

    //填充Odometry消息
    nav_msgs::Odometry odom;
    odom.header.stamp = current_time;
    odom.header.frame_id = "odom";

    //设置位置
    odom.pose.pose.position.x = x;
    odom.pose.pose.position.y = y;
    odom.pose.pose.position.z = 0.0;
    odom.pose.pose.orientation = odom_quat;

    //设置速度
    odom.child_frame_id = "base_link";
    odom.twist.twist.linear.x = vx;
    odom.twist.twist.linear.y = vy;
    odom.twist.twist.angular.z = vth;

    //发布Odometry消息
    odom_pub.publish(odom);

    last_time = current_time;
    r.sleep();
  }
}


3:订阅Odometry消息

(1) 通过rosbag订阅

rostopic echo /odom

(2) 通过rviz查看
打开rviz

rosrun rviz rviz

Fixed Frame修改为base_link,添加Odometry并将Topic设为/odom(3) 编写程序打印

#include "ros/ros.h"
#include "nav_msgs/Odometry.h"
#include "tf/transform_listener.h"

void OdomCallback(const nav_msgs::Odometry::ConstPtr &msg)
{

    double x, y, z;
    double roll, pitch, yaw;
    x = msg->pose.pose.position.x;
    y = msg->pose.pose.position.y;
    z = msg->pose.pose.position.z;
    tf::Quaternion quat;                                     //定义一个四元数
    tf::quaternionMsgToTF(msg->pose.pose.orientation, quat); //取出方向存储于四元数
    tf::Matrix3x3(quat).getRPY(roll, pitch, yaw);

    ROS_INFO("Odom: %f, %f, %f, %f, %f, %f", x, y, z, roll, pitch, yaw);
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "listener");
    ros::NodeHandle node;
    ros::Subscriber subOdom = node.subscribe("odom", 1000, OdomCallback);
    ros::spin();
    return 0;
}

【完】



下一节会介绍陀螺仪Imu数据的发布和订阅

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

【cartographer_ros】四: 发布和订阅里程计odom信息 的相关文章

随机推荐

  • 【RocksDB】Ubuntu20.04下编译rocksdb

    前言 我在刚学rocksdb的时候是在2022年 但是网上的资源很少 查了好久才把rocksdb安装成功 在这里向大家分享一下我的经历 安装过程中也报了很多错误 希望大家不要迷路 首先 在虚拟机里面安装依赖的包以及组件 总共七个依赖包和组件
  • Java 抽象类和普通类、接口的区别——看完你就顿悟了

    Java 抽象类和普通类 接口的区别 看完你就顿悟了 标签 java抽象类概念理解抽象类与接口区别抽象类与普通类区别 2017 05 04 16 26 1029人阅读 评论 0 收藏 举报 分类 Java 17 版权声明 本文为博主csdn
  • 3D语音天气球(源代码分享)——通过天气服务动态创建3D球

    转载请注明本文出自大苞米的博客 http blog csdn net a396901990 谢谢支持 开篇废话 这个项目准备分四部分介绍 一 创建可旋转的 3D球 3D语音天气球 源代码分享 创建可旋转的3D球 二 通过天气服务 从网络获取
  • The MRC database dictionary之FAM库 ( familiarity 熟悉程度)

    breakfast 657 afternoon 655 clothes 652 bedroom 646 dad 646 girl 645 radio 644 book 643 newspaper 641 water 641 big 640
  • Linux系统下卸载VMware Workstation软件

    之所以写这篇文的原因是自己linux台式电脑上需要卸载VMware Workstation软件 网上检索了很多关键词 搜索到的大都是卸载vm虚拟机内安装的Linux操作系统 可能就是这方面的说明内容太少了 在此记录一下 说不定以后就能用上了
  • Flutter使组件居于屏幕中间

    有多种方式可以使组件居于屏幕中间 以下是其中的几种 1 使用 Center 组件将子组件居中 dart Center child YourWidget 2 使用 Align 组件指定子组件的对齐方式 将其居中 dart Align alig
  • CSS的BEM命名规范

    BEM的意思就是块 block 元素 element 修饰符 modifier 是由Yandex团队提出的一种CSS命名方法 其背后的想法是将用户界面分为独立的块 即使使用复杂的UI 这也使界面开发变得容易和快速 并且允许重用现有代码而无需
  • python库是什么

    1 概念 库的概念是具有相关功能模块的集合 这也是Python的一大特色之一 2 库的分类 在Python语言的库中 分为Python标准库和Python的第三方库 python的标准库是随着pyhon安装的时候默认自带的库 python的
  • OkHttp的特性优点及爬虫示例

    OkHttp是一个Java和Android应用程序的HTTP客户端库 旨在提高资源加载速度和节省带宽 与其他类似的库相比 它具有以下优点和区别 一 OkHttp的特性和优点 支持HTTP 2协议 可提高效率和速度 支持连接池 减少请求延迟
  • 【剑指offer】面试题39:二叉树的深度

    一 题目描述 输入一棵二叉树 求该树的深度 从根结点到叶结点依次经过的结点 含根 叶结点 形成树的一条路径 最长路径的长度为树的深度 二 解题思路 递归思想 1 如果一棵树只有一个节点 那么深度为1 2 如果根节点只有左子树而没有右子树 那
  • 【python】【leetcode】【算法题目389—Find the Difference】

    一 题目描述 题目原文 Given two strings s and t which consist of only lowercase letters String t is generated by random shuffling
  • 从一道题目学习Nunjucks模板

    Nunjucks简介 Nunjucks 是一个功能丰富 强大的 JavaScript 专用模板引擎 Nunjucks 提供丰富的语言特性和块继承 自动转移 宏和异步控制等等 重点要关注的是 Nunjucks 模板引擎的代码在沙箱环境中运行
  • Matplotlib课程–学习Python数据可视化

    Learn the basics of Matplotlib in this crash course tutorial Matplotlib is an amazing data visualization library for Pyt
  • 详解Java锁对象

    1 Synchronized 1 1 synchronized特性 1 互斥 synchronized会起到互斥效果 某个线程执行到某个对象的synchronized中时 其他线程如果也执行到同一个对象synchronized就会阻塞等待
  • Python项目:学生信息管理系统(完整版)

    本文是基于上一篇 python项目 学生信息管理系统 初版 进行了完善 并添加了新的功能 主要包括有 完善部分 输入错误 无数据查询等异常错误 新的功能 文件的操作 文件的读写 其中重点是对文本字符串的详细解析 关于整个解析拆解和重组详见代
  • Map分类与常见情况

    java为数据结构中的映射定义了一个接口java util Map 它有四个实现类 分别是HashMap Hashtable LinkedHashMap 和TreeMap Map主要用于存储健值对 根据键得到值 因此不允许键重复 重复了覆盖
  • 计算机网络---流量控制与可靠传输机制

    一 数据链路层的流量控制 较高的发送速度和较低的接收能力的不匹配 会造成传输出错 因此流量控制也是数据链路层的一项重要工作 数据链路层的流量控制是点对点 而传输层的流量控制是端到端的 数据链路层流量控制手段 接收方收不下就不回复确认 传输层
  • Blink 源码编译

    参考 http fetching118 com article 5 html 帮助文档 http fetching118 com blink doc quickstart scala shell quickstart html 1 从Git
  • 由于找不到msvcr120.dll,无法继续执行代码怎么修复,可以使用这个三个方法

    msvcr120 dll是 Microsoft Visual C Redistributable 中的一个文件 是Windows系统非常重要组件 它包含了大量用于 C 程序的函数和类库 这个文件用于一些应用程序或游戏 如果丢失或受损 就可能
  • 【cartographer_ros】四: 发布和订阅里程计odom信息

    上一节介绍了激光雷达Scan传感数据的订阅和发布 本节会介绍里程计Odom数据的发布和订阅 里程计在cartographer中主要用于前端位置预估和后端优化 官方文档 http wiki ros org navigation Tutoria