Odometry的发布和发布odom到base_link的tf变换

转载自http://www.ncnynl.com/archives/201702/1328.html

ROS发布nav_msgs/Odometry消息,以及通过tf从“odom”坐标系到“base_link”坐标系的转换。

在ROS上发布Odometry信息

导航包使用tf来确定机器人在世界中的位置,并将传感器数据与静态地图相关联。然而,tf不提供关于机器人的速度的任何信息。因此,导航包要求任何odometry源通过ROS发布包含速度信息的transform和nav_msgs/Odometry消息。

nav_msgs/Odometry消息

nav_msgs/Odometry信息存储在自由空间的机器人的位置和速度的估计:

# This represents an estimate of a position and velocity in free space.
# 这表示对自由空间中的位置和速度的估计
# The pose in this message should be specified in the coordinate frame given by header.frame_id.
# 此消息中的姿势应在由header.frame_id给定的坐标系中指定
# The twist in this message should be specified in the coordinate frame given by the child_frame_id
# 这个消息中的twist应该在由child_frame_id给出的坐标系指定
Header header
string child_frame_id
geometry_msgs/PoseWithCovariance pose
geometry_msgs/TwistWithCovariance twist

下面是更详细的消息类型

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

该消息中的姿势(pose)对应于机器人在世界坐标系中的估计位置以及该姿势估计特定的可选协方差。

该消息中的速度(twist)对应于机器人在子坐标系的速度,通常是移动基站的坐标系,以及该速度估计特定的可选协方差。

使用tf发布Odometry变换

变换配置教程中所讨论的,“tf”软件库负责管理与变换树中的机器人相关的坐标系之间的关系。

因此,任何odometry(里程)源都必须发布其管理的坐标系的相关信息。

编写代码

我们将编写一些用于通过ROS发布 nav_msgs/Odometry消息的示例代码,以及使用tf的虚拟机器人的变换。

catkin_create_pkg Odom tf nav_msgs roscpp rospy

#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();
  }
}

代码解释:

  • 代码:
#include <tf/transform_broadcaster.h>
#include <nav_msgs/Odometry.h>
  • 解释:我们发布odom坐标系到base_link坐标系的变换和nav_msgs/Odometry消息。需要包含相关头文件
  • 代码:
ros::Publisher odom_pub = n.advertise<nav_msgs::Odometry>("odom", 50);
tf::TransformBroadcaster odom_broadcaster;
  • 解释:创建ros::Publisher和tf::TransformBroadcaster实例,以便能够分别使用ROS和tf发送消息。
  • 代码:
  double x = 0.0;
  double y = 0.0;
  double th = 0.0;
  • 解释:我们假设机器人最初从“odom”坐标系的原点开始
  • 代码:
 double vx = 0.1;
 double vy = -0.1;
 double vth = 0.1;
  • 解释:在这里,我们将设置一些速度,其将导致“base_link”坐标系相对于“odom”坐标系,在x方向上以0.1m/s,在y方向上以-0.1m/s的速率和在th方向以0.1rad/s角度移动。这让虚拟机器人走一个圆圈。
  • 代码:
ros::Rate r(1.0);
  • 解释:我们将在这个例子中以1Hz的速率发布里程计信息,以使自我检查更容易,大多数系统将希望以更高的速率发布里程消息。
  • 代码:
//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);
  • 解释:

    • 我们通常尝试使用我们系统中所有消息的3D版本,以允许2D和3D组件在适当的时候一起工作,并将我们要创建的消息数量保持在最小。
    • 因此,有必要将我们用于里程的偏航值转换为四元数而发送出去。
    • 幸运的是,tf提供了允许从偏航值容易地创建四元数并且容易地访问四元数的偏航值的功能。
  • 代码:
//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";
  • 解释:

    • 这里我们将创建一个TransformStamped消息,我们将通过tf发送。
    • 我们想在“current_time”发布从“odom”坐标系到“base_link”坐标系的转换。
    • 因此,我们将相应地设置消息的头部和child_frame_id,确保使用“odom”作为父坐标系,“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);
  • 解释:这里我们从我们的odometry数据填充变换消息,然后使用我们的TransformBroadcaster发送变换。
  • 代码:
//next, we‘ll publish the odometry message over ROS
nav_msgs::Odometry odom;
odom.header.stamp = current_time;
odom.header.frame_id = "odom";
  • 解释:

    • 我们还需要发布nav_msgs/Odometry消息,以便导航堆栈可以从中获取速度信息。
    • 我们将消息的头部设置为current_time和“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;
  • 解释:

    • 这将使用里程数据填充消息,并通过线路发送。
    • 我们将消息的child_frame_id设置为“base_link”坐标系,因为这是我们发送速度信息的坐标系。

CMakeLists.txt

add_executable(Odom_exam src/Odom_exam.cpp)
target_link_libraries(Odom_exam ${catkin_LIBRARIES})

时间: 2024-10-05 04:01:43

Odometry的发布和发布odom到base_link的tf变换的相关文章

织梦DedeCMS信息发布员发布文章默认自动审核更新并生成HTML页面

织梦DedeCMS信息发布员发布文章默认自动审核更新并生成HTML页面 一直以为DEDECMS的信息发布员在后台发布文章后,非要管理员审核才能显示,今天一哥们问我这个问题.问:“能不能直接发布,并自动生成HTML,这样就节省了非要管理员来审核的麻烦?”我先跟他讲是不能的,非要管理员审核之后才能显示.呵呵,亏我用了这么长时间了,这么个简单的问题还回答的这么外行! 方法一:仔细研究了一下,是有办法的,让信息发布员的权限能够在发布文章之后自动生成HTML,并自动生成列表页和首页,具体办法如下: if(

VS2012 webservice的创建并在iis上发布,发布完后解决“测试窗体只能用于来自本地计算机的请求.”问题视频教程

VS2012 webservice的创建并在iis上发布,发布完后解决"测试窗体只能用于来自本地计算机的请求."问题视频教程 http://yunpan.cn/cZckwQc7FyFN9 访问密请下载查看  http://download.csdn.net/detail/u014180504/8503089 

首富带你畅谈:蓝绿部署、滚动发布、灰度发布/金丝雀发布

首富带你畅谈:蓝绿部署.滚动发布.灰度发布/金丝雀发布 笔者: 张首富 时间: 2019-01-24晚 QQ群: 895291458 博客地址: www.zhangshoufu.com 根据2018年的DevOps发展报告来看,目前的DevOps发展速度非常之快,已经逐渐成为企业运维的标准方案.DevOps的核心就是敏捷和高效,敏捷和Scrum开发技术曾被认为是最好的技术.既然公司用到了CI/CD肯定就肯定避免不了持续部署,所以我们就需要考虑一套适合我们的发布方式,这个时候我们就需要了解一下这几

jenkins+gitlab+微服务发布+k8s发布

背景:jenkins+gitlab+微服务发布+k8s发布实现自动更新1.配置jenkins pipeline pipeline语法`node {try {stage('代码拉取') {git credentialsId: 'xiongxj', url: '[email protected]:xinjiang.xiong/oam.git' } stage('项目构建') { sh " /opt/software/apache-maven-3.6.0/bin/mvn clean package&q

一文了解蓝绿发布/灰度发布/滚动发布

应用程序升级面临最大挑战是新旧业务切换,将软件从测试的最后阶段带到生产环境,同时要保证系统不间断提供服务. 长期以来,业务升级渐渐形成了几个发布策略:蓝绿发布.灰度发布和滚动发布,目的是尽可能避免因发布导致的流量丢失或服务不可用问题. 一. 蓝绿发布 项目逻辑上分为AB组,在项目系统时,首先把A组从负载均衡中摘除,进行新版本的部署.B组仍然继续提供服务. 当A组升级完毕,负载均衡重新接入A组,再把B组从负载列表中摘除,进行新版本的部署.A组重新提供服务. 最后,B组也升级完成,负载均衡重新接入B

[发布] [插件发布] Discuz网页动物园插件1.0Beta发布!让积分流动起来!

插件发布 插件名称: DZ网页动物园插件 插件来源: 原创插件 适用版本: Discuz! X3 语言编码: GBK简体 UTF8简体 BIG5繁体 UTF8繁体  最后更新时间: 2014-09-12 插件作者:   插件简介: 网页动物园插件,猜动物得积分,多人联机,一起玩,最高分者还有奖!系统整合DZ积分,让积分流动起来!网页FLASH技术制作,手机上也可以玩的哦!手机安装FLASH PALYER即可! 网页动物园插件,猜动物得积分,多人联机,一起玩,最高分者还有奖!系统整合DZ积分,让积

牛腩新闻发布系统-发布

敲牛腩太死脑筋了,发布的时候就是照着牛腩老师的方法去发布.结果到出现这个错误页面的时候就进行不下去了,死在了这个坎上.时间一分一秒过去,但仍解决不出来.只好找人求救了,在亮亮和李芬的帮助下成功解决了.布            发布系统,要先安装IIS,它集成在系统中.只需要找到进行安装就可以了.以Win8为例 打开控制面板- 程序和功能-启用或关闭Windows功能.找到Internet信息服务,如图打上对勾. 点击确定后,程序可能安装的比较慢,耐心等待,安装完成后.然后打开控制面板-管理工具.

SQL Server 发布订阅 发布类型详解

MicrosoftSQL Server 提供了三种复制类型. 每种复制类型都适合于不同应用程序的要求. 根据应用程序需要,可以在拓扑中使用一种或多种复制类型: 快照复制 事务复制 合并复制 为了帮助您选择适当的复制类型,此主题提供了有关下列内容的信息: 复制方案 本部分简要描述了复制的多种常用情况,还提供了指向更加详细描述的链接. 复制类型 本部分描述了每个复制类型所适合的应用程序要求. 在订阅服务器上更新数据 本部分描述了需要在订阅服务器上更新数据的应用程序的可用选项. 我们建议您先要通读方案

【转】如何使用离线博客发布工具发布CSDN的博客文章

目前大部分的博客作者在用Word写博客这件事情上都会遇到以下3个痛点: 1.所有博客平台关闭了文档发布接口,用户无法使用Word,Windows Live Writer等工具来发布博客.使用Word写博客需要在第三方博客平台注册帐号,且需要第三方博客平台提供API接口.目前的有的博客平台均已关闭博客接口,所以无法使用Word来发布博客. 2.发布到博客或公众号平台的图片无法转载.由于所有博客平台,公众号平台(如微信)开启了图片防盗链功能,作者发布到这些平台上的图片则无法转载到其它的网站中,这限制