Cartographer安装测试与模块开发(三)--Cartographer在Gazebo仿真环境下的建图以及建图与定位阶段问题(实车也可参考)

参数介绍

之所以要首先介绍参数而不是实操,是因为大部分建图失败、漂移基本上都是参数设置错误引起的,或者说大部分都是TF存在问题,主要是坐标系Frame之间有冲突或者对不上等原因导致的,因此把参数放在前面介绍,了解了参数和对应作用,在对比各类教程设置时才不会碰运气解决报错。

Cartographer的Launch与Lua文件在两个地方存在,注意区分:

//Launch文件位置1:
carto_ws/src/cartographer_ros/cartographer_ros/launch//Lua文件位置1:
carto_ws/src/cartographer_ros/cartographer_ros/configuration_files
carto_ws/src/cartographer/configuration_files//Launch文件位置2:
carto_ws/install_isolated/share/cartographer_ros/launch//Lua文件位置2:
carto_ws/install_isolated/share/cartographer_ros/configuration_files
carto_ws/install_isolated/share/cartographer/configuration_files

如何使用看每个人的习惯,我个人的习惯是调用install_isolated下面的Launch与Lua,使用的时候基于源文件复制一个自己重命名后的Launch与Lua文件来用,且不将source的代码添加到主目录下面的bashrc内,每次使用手动source setup.bash文件。

使用Gazebo来进行建图时,基于demo_backpack_2d.launch文件来实现,打开文件内容如下:

<launch><param name="/use_sim_time" value="true" /><include file="$(find cartographer_ros)/launch/backpack_2d.launch" /><node name="rviz" pkg="rviz" type="rviz" required="true"args="-d $(find cartographer_ros)/configuration_files/demo_2d.rviz" /><node name="playbag" pkg="rosbag" type="play"args="--clock $(arg bag_filename)" />
</launch>

可以看到文件内主要实现了这样几个功能:

将use_sim_time设置为true,启动了仿真时间

启动了backpack_2d.launch

开启rviz

播放rosbag

继续打开同目录下的backpack_2d.launch,内容如下:

<launch><param name="robot_description"textfile="$(find cartographer_ros)/urdf/backpack_2d.urdf" /><node name="robot_state_publisher" pkg="robot_state_publisher"type="robot_state_publisher" /><node name="cartographer_node" pkg="cartographer_ros"type="cartographer_node" args="-configuration_directory $(find cartographer_ros)/configuration_files-configuration_basename backpack_2d.lua"output="screen"><remap from="echoes" to="horizontal_laser_2d" /></node><node name="cartographer_occupancy_grid_node" pkg="cartographer_ros"type="cartographer_occupancy_grid_node" args="-resolution 0.05" />
</launch>

加载启动了机器人相关的参数和功能

启动了cartographer

remap重映射了激光雷达话题名

启动了cartographer的地图服务

这里因为打算新建一个Launch,所以没必要两个Launch来搞调用,直接将两个内容合成一个Launch就好了,当然需要删掉一些不需要的功能,比如启动了backpack_2d.launch代码不需要了、播放rosbag也不需要、加载启动了机器人相关的参数和功能也删掉(不爱看模型,看坐标系更直观),remap的话题按需修改。

最后合成一个map.launch文件:

<launch><param name="/use_sim_time" value="true" /><node name="cartographer_node" pkg="cartographer_ros"type="cartographer_node" args="-configuration_directory $(find cartographer_ros)/configuration_files-configuration_basename map.lua"output="screen"><remap from="scan" to="scan" /></node><node name="cartographer_occupancy_grid_node" pkg="cartographer_ros"type="cartographer_occupancy_grid_node" args="-resolution 0.05" /><node name="rviz" pkg="rviz" type="rviz" required="true"args="-d $(find cartographer_ros)/configuration_files/demo_2d.rviz" />
</launch>

Launch文件准备好之后,继续调整建图的Lua文件,也就是参数部分,在launch文件内加载cartographer的部分可以注意到加载了backpack2d.lua文件。

找到对应文件,Lua文件也和Launch文件一样存在调用其他文件的情况,为了方便起见我新建了一个Lua,把所有调用涉及到的Lua文件全部转移到着一个文件中了,便于调参和管理。

但是需要注意两点:

1、转移Lua文件参数至一个文件中时注意组合的顺序:一般调用关系下越深层的文件在整合时越要靠上,因为它们之间有调用关系。合成一个文件后如果调用段内容在声明段内容的上面是会报错的,如果搞不清楚就按原来的结构改不要整合了。

2、原来的调用关系下,可能有一些参数是重复的:一般是最外层的参数覆盖深层的的参数,这样安排有利于在建图和定位不同功能下都可以调用同样的Lua文件,只需要在最外层把某些值覆写就可以了,整合为一个文件时注意下这个特性。

接下来进入Lua内开始研究参数,这里为了避免歧义依旧按照源代码的Lua文件结构介绍,backpack_2d.lua文件如下:

include "map_builder.lua"
include "trajectory_builder.lua"options = {map_builder = MAP_BUILDER,trajectory_builder = TRAJECTORY_BUILDER,  map_frame = "map",tracking_frame = "base_link",      --追踪坐标系published_frame = "base_link",     --发布至odom_frame = "odom",provide_odom_frame = true,         --是否需要提供odompublish_frame_projected_to_2d = false,    use_pose_extrapolator = true,use_odometry = false,              --是否使用odomuse_nav_sat = false,use_landmarks = false,num_laser_scans = 0,               --单线激光雷达数num_multi_echo_laser_scans = 1,    --多回波雷达数num_subdivisions_per_laser_scan = 10,num_point_clouds = 0,lookup_transform_timeout_sec = 0.2,submap_publish_period_sec = 0.3,pose_publish_period_sec = 5e-3,trajectory_publish_period_sec = 30e-3,rangefinder_sampling_ratio = 1.,odometry_sampling_ratio = 1.,fixed_frame_pose_sampling_ratio = 1.,imu_sampling_ratio = 1.,landmarks_sampling_ratio = 1.,
}MAP_BUILDER.use_trajectory_builder_2d = true
TRAJECTORY_BUILDER_2D.num_accumulated_range_data = 10return options

其中大部分参数保持默认都不会导致建图失败,最多轻微影响建图效果和速度,但是有几个参数需要重点关注,基本是每个机器都需要根据实际情况调整。

首先是:

num_laser_scans = 0,

num_multi_echo_laser_scans = 1,

两个参数,Cartographer默认使用的雷达不是常见的发出Laserscan的雷达,这一点在第一篇文章跑Demo的时候提到过,因此需要将num_multi_echo_laser_scans改为0,num_laser_scans改为1.(如果只使用一个单线激光雷达的话)

如果没有改这个参数,在运行时会出现大概如下的报错:

队列:等待什么(echo,0)

(记不住原始报错信息了,报错的重点是echo、等待数据、queue之类的字眼)

这个参数设置好后就是坐标系三兄弟:

  tracking_frame = "base_link",   
published_frame = "base_link", 
provide_odom_frame = true, 

大部分初学者踩坑都掉在这里了,因为这三个参数如何调整不仅取决于实际仿真环境或者实车环境下发布的TF,而且他们的调整是联动的,先介绍参数具体功能:

tracking_frame要求给出一个坐标系,Cartographer会把机器人其他坐标系转换到这个追踪坐标系,比如雷达坐标系、IMU坐标系等等,这也就要求这个坐标系可以代表整个机器人的运动,通常追踪坐标系可以选择基坐标系或者IMU坐标系,这里将其设置为base_link,因为一般机器人都会有这个坐标系。

published_frame也要求给出一个坐标系,Cartographer会将发布的TF连接在该坐标系上,通常情况是将Map连接到该坐标系上。

provide_odom_frame询问是否需要Cartographer给出odom,如果自己的仿真环境、实车环境带着那当然是false。

注意!以下提到的odom等都为TF中的坐标系,而不是odom话题!

注意点一:如果启动仿真环境或者实车环境后,打印TF树,没有发现tracking_frame赋的值,那么程序是要报错的,可能原因是某些机器人基坐标系是base_footprint或者其他名字,压根没有base_link坐标系,导致其他坐标系没法转移到给定坐标系;或者环境给出了tracking_frame,但是没有发布雷达或者IMU等传感器到该坐标系的TF变换,程序不知道怎么将传感器变换到这个tracking_frame,导致报错。

解决方法也简单,基坐标系问题可以修改tracking_frame的值或者修改机器人urdf的基座标系命名(推荐),缺TF问题,直接手动给出基座标系到雷达等传感器坐标系的静态TF变换,大部分场景下激光雷达应该都是和机器人之间是固连关系吧?

静态TF发布可以写在仿真环境启动的Launch文件里面,具体内容在第二篇文章有提到。

注意点二:published_frame是Cartographer发布的TF所连接的坐标系,一般Cartographer只提供map的坐标系,因此此处也就是给出map->published_frame.但是需要Cartographer提供odom下,此处就变成了odom->published_frame。通常情况下选择odom都没错,但是这些情况下就需要调整了:

provide_odom_frame为false,也就是不需要提供odom坐标系,同时仿真环境也没有提供odom坐标系,这种情况下需要调整为仿真环境中TF树最高的一个坐标系,以本文第二篇提到的TF树为例,如果没有odom的话,就需要填写base_link,这样最终TF树结构为map->base_link。

provide_odom_frame为true,那么此处需要填写TF树最高的一个坐标系,即Cartographer提供map->odom.我们提供odom->published_frame的信息。

开始建图

调整完参数开始建图,通常话题是/scan、/imu、/odom的都不需要额外修改。

启动仿真环境后,启动Cartographer的Launch,如果出现下面类似的ERROR也不要慌:

[rospack] Error: package 'turtlebot3_sim_test' not found
[librospack]: error while executing command
[ERROR] [1753412286.262920514, 142.830000000]: Could not load resource [package://turtlebot3_sim_test/meshes/bases/waffle_pi_base.stl]: Unable to open file "package://turtlebot3_sim_test/meshes/bases/waffle_pi_base.stl".
[rospack] Error: package 'turtlebot3_sim_test' not found
[librospack]: error while executing command
[ERROR] [1753412286.282568001, 142.850000000]: Could not load resource [package://turtlebot3_sim_test/meshes/sensors/lds.stl]: Unable to open file "package://turtlebot3_sim_test/meshes/sensors/lds.stl".
[rospack] Error: package 'turtlebot3_sim_test' not found
[librospack]: error while executing command
[ERROR] [1753412286.300414295, 142.868000000]: Could not load resource [package://turtlebot3_sim_test/meshes/wheels/left_tire.stl]: Unable to open file "package://turtlebot3_sim_test/meshes/wheels/left_tire.stl".
[rospack] Error: package 'turtlebot3_sim_test' not found
[librospack]: error while executing command
[ERROR] [1753412286.317263047, 142.885000000]: Could not load resource [package://turtlebot3_sim_test/meshes/wheels/right_tire.stl]: Unable to open file "package://turtlebot3_sim_test/meshes/wheels/right_tire.stl".

这是因为仿真环境的功能包放在了Cartographer外面,工作空间不同,也没有在bashrc里面写source,因此模型的加载出现错误,会导致rviz看不见模型,完全不影响功能,反而有利于看TF,好事。

启动后可以看到TF:

接下来就可以操作虚拟环境的小车开始运动来进行建图了。

建图完毕后时用下面的代码保存地图:

1、轨迹停止更新(建图产生的submap都在轨迹0上),这个代码有时执行时会和卡住一样,不要着急,他只有轨迹彻底完成才会输出信息,有的时候建图太慢导致堆积了很多帧没有处理完让他处理就好了

rosservice call /finish_trajectory 0

2、保存地图至指定位置(有不少教程花括号漏了后半截)

rosservice call /write_state "{filename: '<绝对路径>/***.pbstream'}"

3、将Cartographer产生的pbstream地图转化为ROS常用地图格式文件:.yaml和.pgm文件(需要就执行,也可以当作可视化地图用)

rosrun cartographer_ros cartographer_pbstream_to_ros_map -map_filestem=绝对路径/地图名字 -pbstream_filename=绝对路径/地图名字.pbstream -resolution=0.05

至此建图流程就结束了,下面汇总下可能会出现的问题,以下也有可能在定位阶段出现问题:

问题一:TF类报错,各类TF不存在、父子坐标系冲突、小车建图漂移等等

首先检查Launch中是否启用了虚拟时间,接下来按照上文提到的Lua文件中的坐标三兄弟,检查自己的设置是否正确,检查建议采用关闭Cartographer,先看仿真环境的TF树正不正确,再启动两者结合报错信息查看。

下面给出常用的TF排查命令:

//打印当前TF树结构
rosrun rqt_tf_tree rqt_tf_tree//查看指定两个坐标之间的坐标变换
rosrun tf tf_echo frame1 frame2

问题二:静止状态正常,小车一开始运动rviz中激光帧就开始乱飞或者扭曲变形,具体表现为激光帧乱动、等比例缩小、变为一条线或者一个点。

检查在基坐标系与传感器坐标系的变换,如果使用了静态坐标发布,是否设置在了变化?建议设置为0 0 0 0 0 0也就是重合。如我之前设置了z轴偏移:

  • <node pkg="tf2_ros" type="static_transform_publisher" name="base_link_to_base_scan" args="0.0 0.0 0.5 0.0 0.0 0.0 base_link base_scan" />

 以上变化导致我的小车在运动时激光帧出现了旋转,变成了垂直于地面,在rvzi中表现为变成一条线。

问题三:建图时空地出现无法去除的灰色或者障碍内部变成白色

障碍内部入侵:

出现灰色区域:

以上主要是参数的问题,可以在Lua文件里面调整击中和未命中的概率,同时也有可能与机器人的速度有关,尤其是机器人转弯速度过快,电脑性能不够(很多使用虚拟机)也有可能影响。

其中障碍内部入侵主要是因为机器人转弯过快且传感器频率、性能不够导致的,一般降低机器人移动速度能有效缓解。

出现灰色区域这一现象主要影响视觉观感,对定位等功能完全不受影响,但如果非常在意,可以找到TRAJECTORY_BUILDER_2D对应Lua文件,调整:

submaps = {
...
...hit_probability = 0.55,miss_probability = 0.46,  --0.49
...
}

其中hit可以让黑色障碍物更快变黑,miss可以让未知区域更快变白,适当降低miss值可以有效降低灰色区域,但是不要降的过低,将会导致障碍也更容易变白,适当降低加上灰色区域多走一步就能有效解决问题。

最后建图如下(80*80M):

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

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

相关文章

uniapp nvue开发App 横竖屏切换丢失上下文导致 setTimeout和clearTimeout报错

报错内容如下 [JS Framework] Failed to find taskCenter (35). [JS Framework] Failed to execute the callback function:TypeError: c.clearTimeout is not a function reportJSException >>>> exception function:__WEEX_CALL_JAVASCRIPT__, exception:JavaSc…

Mirauge3D 赋能:全自动建模,让城市规划与建筑设计拥有高分辨率实景三维模型

在数字化浪潮席卷各行各业的当下&#xff0c;高精度、多元化的空间数据已成为基础测绘、智慧城市建设、自然资源管理等领域高质量发展的核心支撑。从城市交通网络的智能规划到国土空间的优化配置&#xff0c;从灾害监测的精准预警到生态环境保护的科学决策&#xff0c;空间数据…

Javaweb————学习javaweb的预备知识

❤️❤️❤️一.javase,javaweb,javaee的区别和联系 &#x1f499;&#x1f499;&#x1f499;javase: 通俗的来讲就是java技术栈&#xff0c;做java相关开发的基础&#xff0c;比如javaweb&#xff0c;javaee开发都是必备javase的基础的&#xff0c;包括java语言基础&#xff…

zabbix服务自动发现、自动注册及配置钉钉告警(小白的“升级打怪”成长之路)

目录 一、自动发现及自动注册 1、自动发现 2、自动注册规则 二、监控告警并发送电子邮件 1、设定发邮件的地址 2、设定发邮件的用户 3、设定监控及触发的条件 4、开始告警并设置触发发邮件 三、钉钉告警 1、配置zabbix-server 2、配置监控及触发 3、web页面操作 4、…

OSPF多区域

OSPF多区域划分的必要性 OSPF单区域存在的问题 LSDB 庞大&#xff0c;占用内存大&#xff0c;SPF计算开销大。 LSA洪泛范围大&#xff0c;拓扑变化影响范围大。 路由不能被汇总&#xff0c;路由表庞大&#xff0c;查找路由开销大 解决办法 划分区域可以解决上述问题 每个区域独…

质数、因数、最大公约数经典问题整理

1、计数质数 MX 5000000 is_prime [1] * MX is_prime[0] is_prime[1] 0 for i in range(2, MX):if is_prime[i]:for j in range(i * i, MX, i):is_prime[j] 0class Solution:def countPrimes(self, n: int) -> int:return sum(is_prime[:n]) 2、序列中不同最大公约数的…

Java NIO FileChannel在大文件传输中的性能优化实践指南

Java NIO FileChannel在大文件传输中的性能优化实践指南 在现代分布式系统中&#xff0c;海量数据的存储与传输成为常见需求。Java NIO引入的FileChannel提供了高效的文件读写能力&#xff0c;尤其适合大文件传输场景。本文从原理深度解析出发&#xff0c;结合生产环境实战经验…

SQLite Insert 语句详解

SQLite Insert 语句详解 SQLite 是一种轻量级的数据库管理系统,它以其简洁的设计、强大的功能和易于使用而闻名。在 SQLite 中,INSERT 语句用于向数据库表中添加新数据。本文将详细介绍 SQLite 的 INSERT 语句,包括其基本语法、使用方法以及一些高级特性。 基本语法 SQLi…

git更新内核补丁完整指南

Git操作完整指南 📋 目录 项目概述 Git基础配置 日常操作流程 补丁更新操作 分支管理 冲突解决 常见问题 最佳实践 命令速查表 🎯 项目概述 </

关于回归决策树CART生成算法中的最优化算法详解

首先&#xff0c;一共比如有M个特征&#xff0c;N个样本&#xff0c;对于每一个特征j&#xff0c;遍历其中的N个样本&#xff0c;得到N个值中&#xff0c;最小的值&#xff0c;作为这个特征的最优切分点&#xff0c;而其中的c1&#xff0c;c2是可以直接得到的。然后&#xff0c…

Ubuntu 环境下创建并启动一个 MediaMTX 的 systemd 服务

文章目录一、简介二、安装及使用三、创建系统服务小结一、简介 MediaMTX 是一个现代、高性能、跨平台的 流媒体服务器&#xff0c;主要用于接收、转发、转码和分发 音视频流&#xff0c;支持多种协议。它的前身是 rtsp-simple-server&#xff0c;后来重命名为 MediaMTX&#x…

在React中,函数式组件和类组件各有优缺点

函数式组件&#xff1a;无this&#xff0c;无生命周期&#xff0c;配合使用useEffect&#xff0c; 可使用Hooks。 类组件&#xff1a;有生命周期&#xff0c;状态管理&#xff0c;无Hooks&#xff0c;适用于需要明确生命周期方法和实例方法的场景。 函数式组件 优点&#xff1a…

【SketchUp插件推荐】Profile Builder 4.0 中文版下载安装使用教程(含语言设置图解)

一、插件简介 Profile Builder 4.0 是一款适用于 SketchUp 2017-2024 的高效参数化建模插件&#xff0c;中文名称为「参数化造型建模工具」。该插件基于参数化设计原理&#xff0c;允许用户通过简单的路径定义和参数设定&#xff0c;快速生成智能模型&#xff0c;从而大幅提高…

【小沐学GIS】基于Unity3d绘制三维数字地球Earth(Unity3d、OpenGL、GIS)

&#x1f37a;三维数字地球GIS系列相关文章如下&#x1f37a;&#xff1a;1【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第一期2【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;OpenGL、glfw、glut&#xff09;第二期3【小沐学GI…

ARM汇编的一些编写和调用规范总结

ARM汇编在格式上有少数硬性要求&#xff0c;在排版上几乎没什么硬性要求&#xff0c;都不多&#xff0c;以下分别说明。格式要求 ARM 汇编有一些格式上的硬性要求&#xff0c;这些规则由汇编器&#xff08;如 GNU 的gas、ARM 官方的armasm&#xff09;强制执行&#xff0c;违反…

FastAPI框架下集成智谱大模型的RAG流式响应服务框架

RAG&#xff08;检索增强生成&#xff09;是结合检索与生成式 AI 的技术框架。核心逻辑是先从外部知识库精准检索相关信息&#xff0c;再将其作为上下文输入大模型生成回答。技术上依赖检索引擎&#xff08;如向量数据库、BM25&#xff09;、大语言模型&#xff08;如 GPT、LLa…

基于深度学习的胸部 X 光图像肺炎分类系统(三)

目录 二分类胸片判断&#xff1a; 1. 数据加载时指定了两类标签 2. 损失函数用了二分类专用的 3. 输出层只有 1 个神经元&#xff0c;用了sigmoid激活函数 4. 预测时用 0.5 作为分类阈值 二分类胸片判断&#xff1a; import numpy as np import matplotlib.pyplot as plt f…

深入理解 BIO、NIO、AIO

目录 一、同步与非同步 二、阻塞与非阻塞 三、BIO&#xff08;Blocking I/O&#xff0c;阻塞I/O&#xff09; 四、NIO&#xff08;Non-blocking I/O&#xff0c;非阻塞I/O&#xff09; 五、AIO&#xff08;Asynchronous I/O&#xff0c;异步I/O&#xff09; 同步阻塞&…

电脑无法识别固态硬盘怎么办?

随着固态硬盘&#xff08;SSD&#xff09;越来越普及&#xff0c;不少用户在给电脑更换、加装SSD时会遇到一个让人头大的问题——电脑识别不了固态硬盘。可能是开不了机&#xff0c;或者在“此电脑”中找不到硬盘&#xff0c;甚至连系统安装界面都提示“找不到驱动器”。这时候…

Kingbasepostgis 安装实践

文章目录前言一、安装准备1.1 部署方案规划1.2 SELINUX、防火墙状态检查1.3 操作系统时间检查1.4 创建用户及密码1.5 目录创建1.6 操作系统参数配置1.6.1 配置limits.conf文件二、安装2.1 上传安装包以及license授权文件2.2 拷贝安装文件2.3 命令行方式安装2.3.1简介2.3.2 许可…