ROS里程计:navigation/Tutorials/RobotSetup/Odom

2023-11-19

通过ROS发布里程表信息

描述:本教程提供了一个发布导航堆栈的里程表信息的示例。它涵盖了通过ROS发布nav_msgs / Odometry消息,以及通过 tf 从“ odom”坐标系到“ base_link”坐标系的转换。

教程级别:初学者

1、通过ROS发布里程表信息

导航堆栈使用tf确定机器人在世界上的位置,并将传感器数据与静态地图相关联。但是,tf没有提供有关机器人速度的任何信息。因此,导航堆栈要求所有测距源都通过包含速度信息的ROS发布转换和nav_msgs / Odometry消息。本教程介绍了nav_msgs / Odometry消息,并提供了示例代码,用于发布消息并分别通过ROS和tf进行转换。

目录
通过 ROS 发布里程表信息
nav_msgs / Odometry 消息
使用 tf 发布 Odometry 转换
编写代码

2、nav_msgs / Odometry消息

所述nav_msgs /里程计信息存储在自由空间中的机器人的位置和速度的估计值:

#表示对自由空间中的位置和速度的估计。  
#此消息中的姿势应在header.frame_id给定的坐标系中指定。
#此消息中的扭曲应在child_frame_id给定的坐标系中指定
Header header
string child_frame_id
geometry_msgs/PoseWithCovariance pose
geometry_msgs/TwistWithCovariance twist

此消息中的姿势对应于机器人在里程表中的估计位置,以及用于确定该姿势估计值的可选协方差。该消息中的扭曲对应于机器人在子框架(通常是移动基座的坐标框架)中的速度,以及用于确定该速度估计值的可选协方差。

3、使用tf发布Odometry转换

正如“转换配置”教程中讨论的那样,“ tf ”软件库负责管理与转换树中与机器人相关的坐标系之间的关系。因此,任何里程表源都必须发布有关其管理的坐标系的信息。下面的代码假定您具有tf的基本知识,阅读Transform Configuration教程就足够了。

4、编写代码

在本节中,我们将编写一些示例代码,这些代码用于通过ROS发布nav_msgs / Odometry消息,以及使用tf对仅绕圈行驶的假机器人进行转换。我们将首先完整地显示代码,并在下面逐条进行说明。

将依赖项添加到包的manifest.xml中

<depend package =“ tf” />
<depend package =“ nav_msgs” />

切换行号显示

#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::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();               // check for incoming messages
    current_time = ros::Time::now();

    //compute odometry in a typical way given the velocities of the robot
    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;

    //since all odometry is 6DOF we'll need a quaternion created from yaw
    geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(th);

    //first, we'll publish the transform over tf
    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;

    //send the transform
    odom_broadcaster.sendTransform(odom_trans);

    //next, we'll publish the odometry message over ROS
    nav_msgs::Odometry odom;
    odom.header.stamp = current_time;
    odom.header.frame_id = "odom";

    //set the position
    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;

    //set the velocity
    odom.child_frame_id = "base_link";
    odom.twist.twist.linear.x = vx;
    odom.twist.twist.linear.y = vy;
    odom.twist.twist.angular.z = vth;

    //publish the message
    odom_pub.publish(odom);

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

好的,既然您已经有机会查看所有内容,那么让我们详细分解代码的重要部分。

   2 #include <tf/transform_broadcaster.h>
   3 #include <nav_msgs/Odometry.h>
   4 

由于我们将同时发布从“ odom”坐标系到“ base_link”坐标系的转换以及nav_msgs / Odometry消息,因此我们需要包括相关的头文件。

   9   ros::Publisher odom_pub = n.advertise<nav_msgs::Odometry>("odom", 50);
  10   tf::TransformBroadcaster odom_broadcaster;

我们需要同时创建一个ros :: Publisher和一个tf :: TransformBroadcaster,以便能够分别使用ROS和tf发送消息。

  12   double x = 0.0;
  13   double y = 0.0;
  14   double th = 0.0;

我们假设机器人最初从“ odom”坐标系的原点开始。

  16   double vx = 0.1;
  17   double vy = -0.1;
  18   double vth = 0.1;

在这里,我们将设置一些速度,以使“ base_link”框架在“ odom”框架中以x方向0.1m / s,y方向-0.1m / s和0.1rad /沿th方向。这或多或少会导致我们的假机器人绕圈行驶。

24   ros::Rate r(1.0);

在本示例中,我们将以1Hz的速率发布里程表信息,以使自省变得容易,大多数系统将希望以更高的速率发布里程表。

  30     //根据机器人的速度以典型方式计算里程     
  30     //compute odometry in a typical way given the velocities of the robot
  31     double dt = (current_time - last_time).toSec();
  32     double delta_x = (vx * cos(th) - vy * sin(th)) * dt;
  33     double delta_y = (vx * sin(th) + vy * cos(th)) * dt;
  34     double delta_th = vth * dt;
  35 
  36     x += delta_x;
  37     y += delta_y;
  38     th += delta_th;

在这里,我们将基于设置的恒定速度更新里程计信息。真正的里程表系统当然会集成计算出的速度。

  40     //由于所有里程表均为6DOF,因此我们需要使用偏航
  40     //since all odometry is 6DOF we'll need a quaternion created from yaw
  41     geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(th);

我们通常会尝试使用系统中所有消息的3D版本,以允许2D和3D组件在适当的时候一起工作,并使我们必须创建的消息数量保持最少。因此,有必要将用于测距的偏航值转换为四元数以通过导线发送。幸运的是,tf提供了允许从偏航值轻松创建四元数并轻松访问来自四元数的偏航值的功能。

  43     //首先,我们将在tf 上发布转换  
  43     //first, we'll publish the transform over tf
  44     geometry_msgs::TransformStamped odom_trans;
  45     odom_trans.header.stamp = current_time;
  46     odom_trans.header.frame_id = "odom";
  47     odom_trans.child_frame_id = "base_link";

在这里,我们将创建一个TransformStamped消息,该消息将通过tf发送出去。我们要在current_time发布从“ odom”框架到“ base_link”框架的转换。因此,我们将相应地设置消息的标题和child_frame_id,确保使用“ odom”作为父坐标框架,并使用“ base_link”作为子坐标框架。

  49     odom_trans.transform.translation.x = x;
  50     odom_trans.transform.translation.y = y;
  51     odom_trans.transform.translation.z = 0.0;
  52     odom_trans.transform.rotation = odom_quat;
  53 
  54     //send the transform
  55     odom_broadcaster.sendTransform(odom_trans);

在这里,我们从里程数数据中填写转换消息,然后使用TransformBroadcaster发送转换。

  57     //接下来,我们将通过ROS 发布测距消息     
  57     //next, we'll publish the odometry message over ROS
  58     nav_msgs::Odometry odom;
  59     odom.header.stamp = current_time;
  60     odom.header.frame_id = "odom";

我们还需要发布nav_msgs / Odometry消息,以便导航堆栈可以从中获取速度信息。我们将消息的标题设置为current_time和“ odom”坐标框架。

  62     //设置位置
  62     //set the position
  63     odom.pose.pose.position.x = x;
  64     odom.pose.pose.position.y = y;
  65     odom.pose.pose.position.z = 0.0;
  66     odom.pose.pose.orientation = odom_quat;
  67 
  68     //设置速度
  68     //set the velocity
  69     odom.child_frame_id = "base_link";
  70     odom.twist.twist.linear.x = vx;
  71     odom.twist.twist.linear.y = vy;
  72     odom.twist.twist.angular.z = vth;

这将使用测距数据填充消息,并将其通过电线发送出去。我们将消息的child_frame_id设置为“ base_link”框架,因为这是我们要在其中发送速度信息的坐标框架。

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

ROS里程计:navigation/Tutorials/RobotSetup/Odom 的相关文章

  • 深度学习实战:利用Xception算法和PaddlePaddle进行鸟类图像识别

    目录 1 引言 2 Xception算法介绍 3 鸟类识别问题介绍 4 数据集 5 使用PaddlePaddle实现Xception
  • Oracle创建新用户以及导入数据表dmp文件

    创建用户名之前 需要以用户管理员身份登陆数据库 1 在创建用户之前 先要创建表空间 其格式为 格式 create tablespace 表间名 datafile 数据文件名 size 表空间大小 例如 SQL gt create table
  • WEB前端网页设计-Bootstrap4 导航栏

    目录 Bootstrap4 导航栏 垂直导航栏 居中对齐的导航栏 不同颜色导航栏 品牌 Logo 折叠导航栏 导航栏使用下拉菜单 导航栏的表单与按钮 导航栏文本 固定导航栏 Bootstrap4 导航栏 导航栏一般放在页面的顶部 我们可以使
  • python中最常用的三大数据提取方法(1)----jsonpath

    1 jsonpath是python最常用提取数据的方法之一 jsonpath用于对json格式的数据进行提取 可以理解为对字典中value值的提取 用来解析多层嵌套的json数据 JsonPath 是一种信息抽取类库 是从JSON文档中抽取
  • 网络三定律:摩尔定律、吉尔德定律和迈特卡夫定律

    网络三定律 摩尔定律 吉尔德定律和迈特卡夫定律 拓展 1 网络论坛三大定律 2 影响世界的三大定律
  • 复杂交通环境感知

    作者 黄浴 编辑 计算机视觉深度学习和自动驾驶 点击下方卡片 关注 自动驾驶之心 公众号 ADAS巨卷干货 即可获取 点击进入 自动驾驶之心 全栈算法 技术交流群 后台回复 领域综述 获取自动驾驶感知定位融合近80篇综述论文 近年来 计算机
  • TIA博途中如何为IO设备分配设备名称

    TIA博途中如何为IO设备分配设备名称 Robot PLC 自动化学院 CSDN博客
  • React 引入ant-design开发指南

    使用create react app搭建react开发环 创建react脚手架 create react app react antd demo 进入react antd demo cd react antd demo 运行react an
  • MYSQL中索引与主键的区别

    MYSQL中索引与主键的区别 索引 索引好比是一本书的目录 可以快速的通过页码找到你需要的那一页 惟一地标识一行 主键 做为数据库表唯一行标识 作为一个可以被外键有效引用的对象 索引是一种特殊的文件 InnoDB数据表上的索引是表空间的一个
  • Unity中的重载和重写

    Unity中的重载和重写 一 重载 二 重写 三 重载和重写的区别 一 重载 重载 两个必须一个可以 参数名必须相同 参数列表必须不同 返回值类型可以不同 代码示例 using System Collections using System
  • Linux 磁盘命令工具 比df更好用

    对于分析磁盘使用情况 有两个非常好用的命令 du 和 df 简单来说 这两个命令的作用是这样的 du 命令 它是英文单词 disk usage 的简写 主要用于查看文件与目录占用多少磁盘空间 df 命令 它是英文单词 disk free 的
  • python爬取证券之星网站

    周末无聊 找点乐子 coding utf 8 import requests from bs4 import BeautifulSoup import random import time 抓取所需内容 user agent Mozilla
  • 安卓逆向学习-Crack01 学习记录

    Crack01 学习记录 要感谢京峰教育 资料下载 https download csdn net download m0 47210241 85053839 利用jadx gui打开 分析代码 package com zhy editVi
  • nodejs封装api

    安装了nodeJs 执行 安装淘宝镜像 npm install g cnpm registry https registry npm taobao org 安装 yarn 我使用这个 淘宝镜像总是莫名其妙各种bug npm install
  • aix安装 php,CNESA

    aix安装samba服务器可以使用两种方式安装 一种是使用rpm包进行安装 一种是使用源码编译安装 一 使用samba的rpm包进行安装 1 下载samba的rpm包 下载地址为http www bullfreeware com searc
  • C++笔记--线程间共享数据

    当线程在访问共享数据的时候 必须制定一些规矩 用来限定线程可访问的数据位 还有 一个线程更新了共享数据 需要对其他线程进行通知 从易用性的角度 同一进程中的多个线程进行数据共享 错误的共享数据使用是产生并发bug的一个主要原因 当涉及到共享
  • 为什么训练集用fit_transform()而测试集用transform()及sklearn.feature_extraction.text.CountVectorizer API详解

    真正讲明白的 https blog csdn net yyhhlancelot article details 85097656 API https scikit learn org stable modules generated skl

随机推荐

  • mysql+mybatis 批量插入与批量更新

    首先批量更新需要增加 数据库的链接必须加上但是数据库连接必须加上 allowMultiQueries true 属性 不然会报错 You have an error in your SQL syntax check the manual t
  • 各种源码下载地址(目前只有ffmpeg和nginx,libcurl,RapidJSON 文档)

    各种源码下载地址 目前只有ffmpeg和nginx libcurl RapidJSON 文档 ffmpeg源码下载地址 http ffmpeg org download html releases nginx源码下载地址 http hg n
  • H5监听移动端物理/浏览器返回键

    JavaScript没有监听物理返回键的API 所以只能使用 popstate 事件监听 工具类如下 export function handleBrowserGoBack back console log back pushHistory
  • 论文阅读——基于深度学习智能垃圾分类

    B Fu S Li J Wei Q Li Q Wang and J Tu A Novel Intelligent Garbage Classification System Based on Deep Learning and an Emb
  • su命令切换用户输入密码后,提示:鉴定故障

    在终端通过su命令切换用户输入密码后 提示 鉴定故障 这是因为在安装linux系统时未设置root用户密码造成的 需要重新设置密码后再切换用户 具体操作命令如下 设置root用户密码 sudo passwd root 切换用户 su
  • 三步搞定ABAP DOI操作EXCEL

    ABAP可以使用OLE与DOI两种方式实现操作EXCEL 使用OLE时 每个单元格的值和样式都需要写代码实现 特别是对于不规则的格式 代码量巨大 而DOI是从服务器已经上传的EXCEL模板中下载模板然后打开修改实现数据保存 当然 也可以直接
  • springboot中的kafka的KafkaTemplate的配置类

    package com lf report utils import org apache kafka clients producer ProducerConfig import org apache kafka common seria
  • opencv 智能答卷识别系统(一)

    目标 这里是2 智能答卷之别系统二 识别答卷答案 识别准号证号码 识别姓名 识别试卷类别 试卷是有标记的 如试卷上方的黑框 排序结构 使用c 的标准排序算法 struct Ruley bool operator const Rect a1
  • 华为OD机试真题-座位调整-2023年OD统一考试(B卷)

    题目描述 疫情期间课堂的座位进行了特殊的调整 不能出现两个同学紧挨着 必须隔至少一个空位 给你一个整数数组 desk表示当前座位的占座情况 由若干 0 和 1 组成 其中 0 表示没有占位 1 表示占位 在不改变原有座位秩序情况下 还能安排
  • C#获取当前路径 -- 7种方法

    目录 一 代码 二 路径区别 三 参考文献 一 代码 推荐使用第3种 internal static class Program static void Main 获取模块的完整路径 string path1 System Diagnost
  • C++:入门学习C++,它在C的基础上做了哪些修改?

    文章目录 命名空间 缺省参数 函数重载 引用 引用作为函数返回值 引用的收益 引用和指针的区别 引用和指针的对比 内联函数 内联函数的特性 内联函数和宏的关系 指针空值问题 命名空间 首先看这样的代码 include
  • vue canvas typescript 绘制时间标尺

    项目中有个需求 将对象一天内对应的不同的状态在时间轴上显示出来 调研的方案有5种 1 时间轴用div画 时间轴上遮罩的状态改变则改变时间轴div本身的颜色 2 时间轴用div画 时间轴上的遮罩用div画 状态改变则改变遮罩div的颜色 时间
  • 详解原码、反码、补码——深入理解补码

    学过计算机原理的人都知道原码 反码 补码 但是有多少人知道为什么会有这三种码呢 这三种码又是用来干嘛的呢 众所周知 在计算机的世界只有01 那么显然所有的数都得转成二进制 这样计算机才能够理解 如何将一个十进制的数转成二进制就不说了 说下原
  • linux文件代理高速下载,告别龟速下载!

    原始下载链接 wget https github com SwinTransformer storage releases download v1 0 0 swin tiny patch4 window7 224 pth 高速下载 wget
  • windows注册表参数(%1,%2,%v)

    windows注册表是不区分大小写的 参数 含义 1 文件路径 2 系统默认的打印机 3 文件扇区 4 端口 D 文件路径 L 文件长路径 V 文件路径 W 当前文件的父目录的路径 参考 https blog csdn net meng s
  • 唯一化算法

    源代码git地址 对于无序列表的唯一化算法 从前往后依次处理节点p 在p的前驱中查找 通过find函数 值相同者 则调用remove函数将相同者删除 template
  • 1093: 数1的个数

    存限制 128 MB 题目描述 给定一个十进制正整数n 1 n 10000 写下从1到n的所有整数 然后数一下其中出现的数字 1 的个数 例如当n 2时 写下1 2 这样只出现了1个 1 当n 12时 写下1 2 3 4 5 6 7 8 9
  • Qt stylesheet border-color属性,QFontMetrics Class

    一 border color border color 属性设置四条边框的颜色 此属性可设置 1 到 4 种颜色 border color 属性是一个简写属性 可设置一个元素的所有边框中可见部分的颜色 或者为 4 个边分别设置不同的颜色 请
  • 程序员常用命令集,只收集名字 ^^

    export PATH home hanmeimei local bin PATH which ls file helloworld objdump help objdump h s d exit o ldd helloworld ulim
  • ROS里程计:navigation/Tutorials/RobotSetup/Odom

    ROS里程计 navigation Tutorials RobotSetup Odom 通过ROS发布里程表信息 1 通过ROS发布里程表信息 2 nav msgs Odometry消息 3 使用tf发布Odometry转换 4 编写代码