机器人--里程计

news2025/6/3 9:19:54

教程

轮式里程计视频讲解

里程计分类

ros--odometry

什么是里程计

里程计是一种利用从移动传感器获得的数据来估计物体位置随时间的变化而改变的方法。该方法被用在许多机器人系统来估计机器人相对于初始位置移动的距离

注意:里程计是一套算法,不是物理硬件。

作用

机器人相对于初始位置移动的位姿信息。

在ros中,通过发布里程计话题odom,其他模块可以订阅这个话题的数据,获取机器人实时的位姿信息。

里程计和TF

既然里程计话题发布机器人的位姿信息,TF也是发布机器人位姿信息,为什么不发布里程计话题就可以了,还要计算出里程之后再发布tf?

特性里程计话题TF(Transform)
数据内容包含位姿(pose)和速度(twist),通常带协方差仅包含坐标系间的刚性变换(平移+旋转)
主要用途提供里程计的完整运动状态(供算法使用)提供坐标系间的空间关系(供可视化、传感器融合等使用)
消费者导航算法(如EKF、路径规划)RViz、传感器数据处理节点、多坐标系协作模块
更新频率通常较低(10-50Hz,取决于传感器)通常较高(与TF广播频率一致,可能100Hz+)
话题名称

不固定,不同的机器人可以使用不同的里程计话题名称,创建话题时需要质地的那个话题名称。

订阅的时候也通过话题名称订阅。

固定话题名称,/tf和/tf_static。所有的TF变化都通过这两个话题发布,再通过looup_transform订阅指定两个坐标系的TF。
RVIZ插件Odometry插件TF插件

RVIZ对TF的依赖要更强些。

里程计在ros中的作用

ros2中的里程计odometry:

# 包含父ID
std_msgs/Header header

# 子ID,即姿势所在的坐标系
string child_frame_id

# 通常相对于父坐标的估计姿态.
geometry_msgs/PoseWithCovariance pose

# 在子坐标系中的线速度和角速度.
geometry_msgs/TwistWithCovariance twist

ros2中的里程计是需要通过传感器比如编码器,IMU等获取机器人的线速度,角速度,加速度等信息来完成填充odometry接口中的数据,之后再以话题的方式发布出去

可见ros2中的里程计不仅可以发布机器人的当前位姿,还包括机器人的线速度和角速度等信息。

里程计的分类

轮式里程计

轮式里程计是通过电机编码器反馈电机转速,再利用电机转速和减速比等物理参数计算出小车轮子的转速,再通过运动学正解计算小车整体的线速度和角速度,也就是里程计需要发布的参数的。

角度累计

不断累计机器人绕Y轴转动的角度yam,其实根据三角函数计算式可知,超过180度就是计算-180度内的角度,超过-180度就是计算180度内的角度,所以,机器人转一圈的范围也就是0~180或者0~-180之间,为了防止角度溢出,我们只需要控制角度累计的角度再-180~180之间即可。

两轮差速位置累计

delta_th = vth * dt;
odom_th_ += delta_th; // 角度累计--姿态累计
delta_x = vx * cos(odom_th_) * dt; // 位姿累计
delta_y = vx * sin(odom_th_) * dt;

适用对象: 专为 两轮差分驱动机器人 设计(如TurtleBot),假设机器人 只有X方向线速度(vx)和Z轴角速度(vth,Y方向速度始终为0。

对于差分驱动机器人:

  1. Y方向速度恒为0(不能横向移动),因此 Y * sin(pZ)Y * cos(pZ) 项为0。

  2. dt 很小,角度变化 delta_th 对位移的影响可忽略,此时方法1是方法2的近似。

通用2D位置累计

pZ += Z * Sampling_Time; // 角度累计
pX += (X * cos(pZ) - Y * sin(pZ)) * Sampling_Time; // 位置累计
pY += (X * sin(pZ) + Y * cos(pZ)) * Sampling_Time;

适用对象: 适用于 任何2D平面运动的机器人(如全向轮、麦克纳姆轮机器人),支持 X/Y方向线速度(X, Y)和Z轴角速度(Z

哪种更准确?

  • 如果机器人 严格两轮差分驱动,且 dt 足够小: 两种方法等效(因为 Y=0,方法2退化为方法1)。

  • 如果机器人 有Y方向速度dt 较大: 必须用方法2,否则会忽略旋转对位移的耦合影响。

  • 如果机器人 快速旋转vth较大): 方法2更准确,方法1会引入误差。

里程累计

里程累计包括位置,即X轴位置和Y轴位置累计和角度累计,三者共同表示机器人的位姿。

注意:一定要线角度累计,再利用累计的角度计算位置累计。

惯性里程计

视觉里程计

激光里程计

ros中的实现--odometry

odometry:

# 包含父ID
std_msgs/Header header

# 子ID,即姿势所在的坐标系
string child_frame_id

# 通常相对于父坐标的估计姿态.
geometry_msgs/PoseWithCovariance pose

# 在子坐标系中的线速度和角速度.
geometry_msgs/TwistWithCovariance twist
odom.child_frame_id = robot_frame_id; 	#里程计TF子坐标
odom.twist.twist.linear.x =  X; # X方向速度
odom.twist.twist.linear.y =  Y; # Y方向速度
odom.twist.twist.angular.z = Z; # 绕Z轴角速度

角速度可以通过IMU获取,或者通过编码器和运动学正解获取机器人整体角速度和线速度,那么XY方向的线速度怎么获取呢?

在轮式里程计中,计算出机器人整体的角速度和线速度之后,可以利用角速度计算出这段时间内的总的旋转角度,再通过总的旋转角度计算出线速度再XY轴上各自的分量,各自分速度再和时间积分就是位置里程。

delta_th = vth * dt;
odom_th_ += delta_th; // 角度累计--姿态累计
delta_x = vx * cos(odom_th_) * dt; // 位姿累计
delta_y = vx * sin(odom_th_) * dt;

里程计和TF广播

里程计是如何完成TF广播的?

里程计代表机器人的位置相对于初始位置的累加变化,即机器人当前位姿。

TF(动态)广播器记录和发布的是两个坐标系之间的实时平移和旋转的坐标系变换关系。

  tf2::Quaternion q;
  q.setRPY(0, 0, odom_th_); // odom_th_是yam旋转角累计
  
  // 发布里程计话题,用于算法
  odom_publisher_->publish(odom_msg);
  // 之后发布TF,用于RVIZ坐标变换
  geometry_msgs::msg::TransformStamped t;

  t.header.stamp = this->get_clock()->now();
  t.header.frame_id = "odom";
  t.child_frame_id = "base_footprint";

  t.transform.translation.x = odom_x_;
  t.transform.translation.y = odom_y_;
  t.transform.translation.z = 0.0;

  t.transform.rotation.x = q[0];
  t.transform.rotation.y = q[1];
  t.transform.rotation.z = q[2];
  t.transform.rotation.w = q[3];

  if (pub_odom_) {
    // 广播里程计TF
    tf_broadcaster_->sendTransform(t);
  }

里程计话题发布

1,创建话题

2,创建话题消息

消息类型:

nav_msgs/msg/Odometry

# 消息中的 pose(位姿) 应该由 header.frame_id 给出的坐标系指定。 
# 消息中的 twist(速度信息) 应该由 child_frame_id 给定的坐标系来指定。

# 包含位姿的父坐标系的 frame_id。
- 这是一个标准的 ROS 2 消息头(Header),包含时间戳和父坐标系 ID。
- `header.frame_id` 表示 **位姿(pose)所在的参考系**,也就是“父坐标系”。
std_msgs/Header header
        builtin_interfaces/Time stamp
                int32 sec
                uint32 nanosec
        string frame_id

string child_frame_id

# 估计的位姿,通常是相对于一个固定的全局世界坐标系。
geometry_msgs/PoseWithCovariance pose
        Pose pose
                Point position
                        float64 x
                        float64 y
                        float64 z
                Quaternion orientation
                        float64 x 0
                        float64 y 0
                        float64 z 0
                        float64 w 1
        float64[36] covariance

# 估计的线速度和角速度是相对于子坐标系的。
geometry_msgs/TwistWithCovariance twist
        Twist twist
                Vector3  linear
                        float64 x
                        float64 y
                        float64 z
                Vector3  angular
                        float64 x
                        float64 y
                        float64 z
        float64[36] covariance

1. std_msgs/Header header

  • 作用:消息的头部信息,包含时间戳和参考坐标系。

    • stamp (builtin_interfaces/Time):

      • sec:时间戳的秒部分(Unix时间)。

      • nanosec:时间戳的纳秒部分(0~999,999,999)。

      • 用途:标识里程计数据的时间点,用于与其他传感器数据同步。

    • frame_id (string):

      • 值示例"odom"

      • 用途:既是里程计的父坐标系,也是pose的参考坐标系,也就是pose的父坐标系,也就是pose是child_frame_id这个坐标系相对于frame_id这个坐标系的pose。

2. string child_frame_id

  • 作用:指定机器人本体的坐标系。

    • 值示例"base_footprint""base_link"

    • 用途:里程计子坐标系,也就是机器人本体坐标系,也是pose和速度信息所在坐标系。

3. geometry_msgs/PoseWithCovariance pose

  • 作用:机器人相对于全局坐标系的位姿(位置+朝向)及其不确定性。

    • pose (geometry_msgs/Pose):

      • position (Point):

        • x, y, z:3D位置坐标(单位:米)。

        • 注意:对于地面机器人,z 通常为0(除非有高度变化)。

      • orientation (Quaternion):

        • x, y, z, w:四元数表示朝向(需归一化)。

        • 默认值(0, 0, 0, 1) 表示无旋转(朝向与父坐标系一致)。

    • covariance (float64[36]):

      • 位姿的6x6协方差矩阵(按行优先排列),表示不确定性:

[x_var, xy, xz, x_roll, x_pitch, x_yaw,
 xy, y_var, yz, y_roll, y_pitch, y_yaw,
 ...]

4. geometry_msgs/TwistWithCovariance twist

  • 作用:机器人本体的线速度和角速度及其不确定性。

    • twist (geometry_msgs/Twist):

      • linear (Vector3):

        • x:前进速度(单位:米/秒,正值为前进)。

        • y:横向速度(正值为左移,差分驱动机器人通常为0)。

        • z:垂直速度(地面机器人通常为0)。

      • angular (Vector3):

        • x:横滚角速度(绕X轴旋转,地面机器人通常为0)。

        • y:俯仰角速度(绕Y轴旋转,地面机器人通常为0)。

        • z:偏航角速度(绕Z轴旋转,单位:弧度/秒,正值为逆时针)。

    • covariance (float64[36]):

      • 速度的6x6协方差矩阵(排列方式同 pose.covariance)。

      • 用途:描述速度测量的噪声特性(如IMU误差)。

协方差的选择

const double odom_pose_covariance[36]   = {1e-3,    0,    0,   0,   0,    0, 
										      0, 1e-3,    0,   0,   0,    0,
										      0,    0,  1e6,   0,   0,    0,
										      0,    0,    0, 1e6,   0,    0,
										      0,    0,    0,   0, 1e6,    0,
										      0,    0,    0,   0,   0,  1e3 };

const double odom_pose_covariance2[36]  = {1e-9,    0,    0,   0,   0,    0, 
										      0, 1e-3, 1e-9,   0,   0,    0,
										      0,    0,  1e6,   0,   0,    0,
										      0,    0,    0, 1e6,   0,    0,
										      0,    0,    0,   0, 1e6,    0,
										      0,    0,    0,   0,   0, 1e-9 };

const double odom_twist_covariance[36]  = {1e-3,    0,    0,   0,   0,    0, 
										      0, 1e-3,    0,   0,   0,    0,
										      0,    0,  1e6,   0,   0,    0,
										      0,    0,    0, 1e6,   0,    0,
										      0,    0,    0,   0, 1e6,    0,
										      0,    0,    0,   0,   0,  1e3 };
										      
const double odom_twist_covariance2[36] = {1e-9,    0,    0,   0,   0,    0, 
										      0, 1e-3, 1e-9,   0,   0,    0,
										      0,    0,  1e6,   0,   0,    0,
										      0,    0,    0, 1e6,   0,    0,
										      0,    0,    0,   0, 1e6,    0,
										      0,    0,    0,   0,   0, 1e-9} ;
什么是协方差矩阵?

在概率机器人学中,协方差矩阵用来表示某个状态变量的不确定性。数值越大,说明该维度上的测量或估计越不可靠。

位姿协方差结构:

[ x_x, x_y, x_z, x_roll, x_pitch, x_yaw,  // x可靠性
  y_x, y_y, y_z, y_roll, y_pitch, y_yaw, // y可靠性
  z_x, z_y, z_z, z_roll, z_pitch, z_yaw, // z可靠性
  roll_x, roll_y, roll_z, roll_roll, roll_pitch, roll_yaw, // roll可靠性
  pitch_x, pitch_y, pitch_z, pitch_roll, pitch_pitch, pitch_yaw, // pitch可靠性
  yaw_x, yaw_y, yaw_z, yaw_roll, yaw_pitch, yaw_yaw ] // yaw可靠性

{1e-3,   0,   0,    0,    0,    0, 
   0, 1e-3,   0,    0,    0,    0,
   0,   0, 1e6,    0,    0,    0,
   0,   0,   0,  1e6,    0,    0,
   0,   0,   0,    0,  1e6,    0,
   0,   0,   0,    0,    0,  1e3}
维度含义说明
xy1e-3X、Y 位置估计较准确
z1e6Z 轴方向不关心或不可靠(如地面机器人)
rollpitch1e6不依赖或无法测量
yaw1e3偏航角有一定误差
  • xy方向:高精度(方差=0.001,置信度高)。

  • z方向:极低精度(方差=1e6,表示忽略此方向,适用于地面机器人)。

  • 旋转(rollpitch):极低精度(方差=1e6,通常地面机器人不关心俯仰/横滚)。

  • yaw方向:中等精度(方差=1000,适用于航向角估计)。

这是一个典型的 2D 地面机器人位姿协方差矩阵

{1e-9,   0,   0,    0,    0,    0, 
   0, 1e-3,1e-9,    0,    0,    0,
   0,   0, 1e6,    0,    0,    0,
   0,   0,   0,  1e6,    0,    0,
   0,   0,   0,    0,  1e6,    0,
   0,   0,   0,    0,    0, 1e-9}
  • 移动的x和旋转的yaw方向:极高精度(方差=1e-9,几乎完全信任)。

位姿协方差结构类似,但表示速度的不确定性(数据可靠性)。

-- 机器人禁止使用高可靠性协方差;运动姿态使用低可靠性协方差。

3,发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2394753.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式——原型设计模式(创建型)

摘要 本文详细介绍了原型设计模式,这是一种创建型设计模式,通过复制现有对象(原型)来创建新对象,避免使用new关键字,可提高性能并简化对象创建逻辑。文章阐述了其优点,如提高性能、动态扩展和简…

通过mqtt 点灯

1 解析mqtt 传过来的json 用cjson 解析。 2 类似mvc的结构,调用具体的动作函数 定义设备处理结构体:使用结构体数组映射设备名称与处理函数,实现可扩展的指令分发分离设备逻辑:为每个设备(如 LED、Motor&#xff0…

大数据-273 Spark MLib - 基础介绍 机器学习算法 决策树 分类原则 分类原理 基尼系数 熵

点一下关注吧!!!非常感谢!!持续更新!!! 大模型篇章已经开始! 目前已经更新到了第 22 篇:大语言模型 22 - MCP 自动操作 FigmaCursor 自动设计原型 Java篇开…

基于 Spring Boot + Vue 的墙绘产品展示交易平台设计与实现【含源码+文档】

项目简介 本系统是一个基于 Spring Boot Vue 技术栈开发的墙绘产品展示交易平台,旨在提供一个高效、便捷的在线商城平台,方便用户浏览、选购墙绘产品,并提供管理员进行商品管理、订单管理等功能。系统采用了前后端分离的架构,前…

【机器学习】支持向量机

文章目录 一、支持向量机简述1.概念2.基本概念3.算法介绍4.线性可分5.算法流程 二、实验1.代码介绍2.模型流程3.实验结果4.实验小结 一、支持向量机简述 1.概念 支持向量机(SVM)是一类按监督学习方式对数据进行二元分类的广义线性分类器,其…

ONLYOFFICE深度解锁系列.4-OnlyOffice客户端原理-真的不支持多端同步

最近很多客户多要求直接部署onlyoffice服务端,还问能否和onlyoffice的客户端进行文件同步,当时真是一脸懵,还有的是老客户,已经安装了onlyoffice协作空间的,也在问如何配置客户端和协作空间的对接。由于问的人太多了,这里统一回复,先说结论,再说原理: 1.onlyoffice document s…

LLMTIME: 不用微调!如何用大模型玩转时间序列预测?

今天是端午节,端午安康!值此传统佳节之际,我想和大家分享一篇关于基于大语言模型的时序预测算法——LLMTIME。随着人工智能技术的飞速发展,利用大型预训练语言模型(LLM)进行时间序列预测成为一个新兴且极具…

2.从0开始搭建vue项目(node.js,vue3,Ts,ES6)

从“0到跑起来一个 Vue 项目”,重点是各个工具之间的关联关系、职责边界和技术演化脉络。 从你写代码 → 到代码能跑起来 → 再到代码可以部署上线,每一步都有不同的工具参与。 😺😺1. 安装 Node.js —— 万事的根基 Node.js 是…

【pycharm】如何连接远程仓库进行版本管理(应用版本)

软件:Pycharm OS:Windows 一、Git基础设置 这里略过Git安装,需要可以参考:windows安装git(全网最详细,保姆教程)-CSDN博客 1. 配置Git 打开GitBash。分次输入下列命令。 git config --…

linux 1.0.7

用户和权限的含义与作用 linux中的用户和文件 用户的权限是非常重要的 而且有些程序需要使用管理员身份去执行 这些都是非常重要的 不可能让所有的人拥有所有的权限 这样的工具可以避免非法的手段来修改计算机中的数据 linux之所以安全还是权限管理做的很棒 每个登录的用户都有…

IEEE P370:用于高达 50 GHz 互连的夹具设计和数据质量公制标准

大多数高频仪器,如矢量网络分析仪 (VNA) 和时域反射仪 (TDR),都可以在同轴接口的末端进行非常好的测量。然而,复杂系统中使用的互连很少具有同轴接口。用于表征这些设备的夹具的设计和实施会对测…

Denoising Autoencoders 视频截图 DAEs简单实现 kaggle 去噪编码器

https://www.bilibili.com/video/BV1syzrYaEtw Denoising Autoencoders (DAEs) 是一种无监督学习模型,属于自动编码器(Autoencoder)的一种扩展形式。它们的目标是通过训练神经网络来学习数据的鲁棒表示(robust representation&a…

GoogLeNet网络模型

GoogLeNet网络模型 诞生背景 在2014年的ImageNet图像识别挑战赛中,一个GoogLeNet的网络架构大放异彩,与VGG不同的是,VGG用的是3*3的卷积,而GoogLeNet从1*1到7*7的卷积核都用,也就是使用不同大小的卷积核组合。 网络…

仿真科普|弥合市场需求断层,高性能仿真,“性能”与“安全”如何兼得?

2025年3月,塔塔科技(Tata Technologies)确认曾在去年遭受勒索软件组织“猎手国际”(Hunters International)的攻击,1.4TB工程数据被窃取,涉及航空发动机热障涂层工艺参数等超过 73 万份文件。 X…

Maven---配置本地仓库

目录 5. 5.1在Maven路径下新建文件夹用于本地仓库存储 5.2 复制本地仓库路径 5.3 找到配置文件路径,使用VSCode方式打开 5.4 新增一行代码 5.5 复制本地仓库路径,设置存储路径 5.1在Maven路径下新建文件夹用于本地仓库存储 5.2 复制本地仓库路径 5…

【C++ 】智能指针:内存管理的 “自动导航仪”

目录 一、引入 二、智能指针的两大特性: 1、RAII 特点: 好处: 2、行为像指针 三、智能指针起初的缺陷:拷贝问题 四、几种智能指针的介绍。 1、C98出现的智能指针——auto_ptr auto_ptr解决上述拷贝构造的问题&#xff1a…

设备制造行业项目管理难点解析,如何有效解决?

在设备制造行业,项目管理是企业运营的核心环节,直接影响项目交付效率、成本控制和盈利能力。然而,由于行业特性复杂、项目周期长、涉及部门多,企业在实际操作中常常面临诸多管理痛点。金众诚工程项目管理系统,依托金蝶…

浅谈 PAM-2 到 PAM-4 的信令技术演变

通信信令技术演进:从 PAM-2 到 PAM-4 在当今数字化高速发展的时代,数据传输需求呈爆炸式增长,行业对通信带宽的要求愈发严苛。为顺应这一趋势,通信信令技术不断革新,曾经占据主导地位的不归零(NRZ&#xff…

Protos-SIP:经典 SIP 协议模糊测试工具!全参数详细教程!Kali Linux教程!

简介 该测试套件的目的是评估会话发起协议 (SIP) 实现的实现级别安全性和稳健性。 Protos-SIP 是一款专为 SIP 协议模糊测试(Fuzzing)设计的工具,最初由 OUSPG(Oulu University Secure Programming Group)开发&#…

复数三角不等式简介及 MATLAB 演示

复数三角不等式简介及 MATLAB 演示 1. 复数三角不等式简介 复数三角不等式(Complex Triangle Inequality)是复数的一种重要性质,它类似于普通的三角不等式,但适用于复数空间。具体来说,复数三角不等式可以描述复数之…