ROS机器人启动move base时代价地图概率性无法加载的原因及解决方法

news2025/1/21 4:53:21

   最近,使用ROS机器人,在启动move_base 节点时,概率性会出现全局和局部代价地图不加载的问题,此时,发布目标点也无法启动路径规划。而且该问题有时候出现概率很低,比如启动10次,会有1次发送该情况,有时候概率又比较高,运气最差的一次,启动了8次才正常启动。

   上图中,是正常情况下,rviz显示的局部代价地图,在确保rviz已经配置了显示局部代价地图后,上述异常情况下,该局部代价地图不会显示。此时,rviz的局部代价地图的map配置中会显示No map received,通过rostopic echo在终端打印局部代价地图信息,会发现该消息没有被发布出来。

   在比赛过程中,若遇到这个问题,纯纯搞心态,初赛中,8分钟的比赛时间,卡在代价地图无法正常加载浪费了至少1分钟,所以还是下定决心要刨根问底,解决这个隐患。

   为了找到异常启动 move_base 节点时程序是否卡在了某个地方,从而导致代价地图没有加载出来,我先后在move_base、costmap_2d、global_planner功能包的初始化函数(构造函数)以及调用的相关函数编写打印了大量的流程运行信息,用来分析程序卡在了什么地方。

在这里插入图片描述

在这里插入图片描述

   经过层层套娃式深入探究和分析,最终确定上述异常的代价地图为正常加载是卡在了位于move_base构造函数中调用的以下函数中

planner_costmap_ros_->start();

   planner_costmap_ros_中的start()函数具体程序位于costmap_2d_ros.cpp中,我添加了标志信息后的程序如下所示:

void Costmap2DROS::start()
{

  
  ROS_INFO("c1");


  std::vector < boost::shared_ptr<Layer> > *plugins = layered_costmap_->getPlugins();

  ROS_INFO("c2");

  // check if we're stopped or just paused
  if (stopped_)
  {
    // if we're stopped we need to re-subscribe to topics
    for (vector<boost::shared_ptr<Layer> >::iterator plugin = plugins->begin(); plugin != plugins->end();
        ++plugin)
    {
      (*plugin)->activate();
    }
    stopped_ = false;
  }
  stop_updates_ = false;

  ROS_INFO("c3");

  // block until the costmap is re-initialized.. meaning one update cycle has run
  ros::Rate r(100.0);

  ROS_INFO("initialized_: %d", initialized_);

  while (ros::ok() && !initialized_)
    r.sleep();

  ROS_INFO("c4");
}

   上述异常导致此处调用start函数时的initialized_值为0,从而卡在了start函数的while循环中,从而使得move_base中planner_costmap_ros_->start()语句后的初始化部分未能执行,从而导致代价地图未能加载。

   正常情况下,调用start函数时initialized_值为1。后来我深入探究了为什么有时候程序运行到planner_costmap_ros_->start()语句时,initialized_值为1(正常情况),有时候initialized_值为0(异常情况)。

   经过层层套娃式分析,最终锁定到了costmap_2d_ros.cpp中的void Costmap2DROS::updateMap()函数中的layered_costmap_->updateMap(x, y, yaw);函数中

void Costmap2DROS::updateMap()
{

  ROS_INFO("true 490");

  if (!stop_updates_)
  {

    ROS_INFO("true 495");

    // get global pose
    geometry_msgs::PoseStamped pose;
    if (getRobotPose (pose))
    {
      double x = pose.pose.position.x,
             y = pose.pose.position.y,
             yaw = tf2::getYaw(pose.pose.orientation);


      ROS_INFO("up1");

      layered_costmap_->updateMap(x, y, yaw);

      ROS_INFO("up2");

      geometry_msgs::PolygonStamped footprint;
      footprint.header.frame_id = global_frame_;
      footprint.header.stamp = ros::Time::now();

      ROS_INFO("up3");

      transformFootprint(x, y, yaw, padded_footprint_, footprint);

      ROS_INFO("up4");

      footprint_pub_.publish(footprint);

      ROS_INFO("up5");

      initialized_ = true;
      ROS_INFO("true 505");
    }
  }
}

   根本原因是正常情况下和异常情况下layered_costmap的updateMap(x, y, yaw)函数执行速度不同,导致了这个将initialized_值置为1的线程与另一个通过planner_costmap_ros_->pause()将initialized_值置为0的线程在正常和异常情况下的执行顺序不同,正常情况下另一个将initialized_值置为0的线程先执行,然后将其值置为1的线程后执行,异常情况下则相反,此时导致本线程程序卡在start函数,而不能正常运行。


   至于该问题的解决方法,我编写了一个Costmap2DROS类的成员函数force_start(),在该函数中将initialized_的值强制置为1。然后在move_base.cpp文件中执行planner_costmap_ros_->start();之前,先执行该planner_costmap_ros_->force_start();语句,将initialized_的值强制置为1,此时,便不会出现上述程序卡在start()函数的情况。

planner_costmap_ros_->force_start();

   添加在costmap_2d_ros.cpp文件中的force_start()函数的具体程序如下:

void Costmap2DROS::force_start()
{
  initialized_ = true;

  ROS_INFO("initialized_ force_start");

}

   添加在costmap_2d_ros.h文件中Costmap2DROS类中的force_start()函数的声明如下:

  /**
   * @brief  initialized_ force_start
   */
  void force_start();

   至此,经过以上修改,在启动move_base 节点时,概率性会出现全局和局部代价地图不加载的问题,就可以得到解决。


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

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

相关文章

ASEMI逆变器专用整流桥GBU812参数,GBU812规格

编辑-Z GBU812参数描述&#xff1a; 型号&#xff1a;GBU812 最大峰值反向电压(VRRM)&#xff1a;1200V 平均整流正向电流(IF)&#xff1a;8A 正向浪涌电流(IFSM)&#xff1a;200A 工作接点温度和储存温度(TJ, Tstg)&#xff1a;-55 to 150℃ 最大热阻(RθJC)&#xff1…

node fs模块readFileSync报错SyntaxError: Unexpected token ‘*‘

node fs模块readFileSync报错SyntaxError: Unexpected token * 1.问题再现2.解决方法 1.问题再现 使用node的fs模块readFileSync读取文件时&#xff0c;报错了SyntaxError: Unexpected token 。文件的读取路径是没有问题的。 看到好像是读不了""也。 2.解决方法 …

08 Ubuntu安装docker || 四十五秒极速安装!真的极快,我使用了镜像

因为我是Ubuntu系统的&#xff0c;所以我下面只演示Ubuntu系统。 我使用的是“清华镜像”所提供的步骤&#xff0c;如果你曾多看过我几篇博客&#xff0c;就知道我真的十分喜欢使用清华镜像。 文末附带其他版本安装方式。 1 &#xff08;删除旧版本&#xff09; 如果你以前…

Anaconda详细安装过程

一、前言 Anaconda是一个开源的Python和R编程语言的发行版本&#xff0c;用于数据科学、机器学习、人工智能和科学计算。它提供了一个集成的平台&#xff0c;包含了大量的开源工具、库和软件包&#xff0c;方便用户进行数据分析、处理和建模。 二、实验环境 WIndows10、11 …

leetcode 415.字符串相加

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;https://leetcode.cn/problems/add-strings/description/ ps&#xff1a; 从两个字符串的末尾开始遍历&#xff0c;依次相加&#xff0c;若大于等于 10 则使用一个变量记录进位&#xff0c;遍历的时候若两个字符串其中一…

vue3 实现简单瀑布流

一、整理思路 实际场景中&#xff0c;瀑布流一般由 父组件 提供 数据列表&#xff0c;子组件渲染每个图片都是根据容器进行 绝对定位 &#xff0c;从而定好自己的位置取出 屏幕的宽度&#xff0c;设定 图片的宽度 固定 为一个值&#xff0c;计算可以铺 多少列按列数 先铺上第一…

【嵌入式】MKV31F512VLL12 微控制器 (MCU) 、Cyclone® IV E EP4CE10E22I8LN,FPGA-现场可编程门阵列芯片

1、MKV31F512VLL12 微控制器 (MCU) 是适用于BLDC、PMSM和ACIM电机控制应用的高性能解决方案。这些MCU采用运行频率为100MHz/120MHz、带数字信号处理 (DSP) 和浮点单元 (FPU) 的ARM Cortex-M4内核。KV3x MCU配备两个采样率高达1.2MS/s的16位ADC、多个控制定时器以及512KB闪存。 …

【SpringCloud】Stream消息通知使用

文章目录 概述标准MQ 配置POMYML 示例消息发送配置RabbitMQ可视化插件消息消费者 遇到的问题复现解决&#xff1a;修改YML注意 概述 屏蔽底层消息中间件的差异,降低切换成本&#xff0c;统一消息的编程模型 官网&#xff1a; https://spring.io/projects/spring-cloud-stream#…

Docker Dockerfile Docker-compose学习笔记

文章目录 Centos环境下安装Docker配置镜像源 Windows环境下安装Docker配置镜像源 使用Dokcer镜像1.获取镜像2.查看镜像信息(1)列出镜像(2)镜像标签(3)镜像详细信息(4)镜像历史 3.搜索镜像4.删除和清理镜像(1)使用标签删除镜像(2)使用ID删除镜像(3)清理镜像 5.创建镜像(1)基于已…

Git分享-规范/建议/技巧

1. Git多人协作开发流程图 1.1 processOn默认的模板 1.2 改造之后 https://www.processon.com/view/link/64ccaf56a433c931b2f9428a 访问密码&#xff1a;512I ① 总流程图 ② feat分支&#xff08;功能/需求 分支&#xff09;流程 ③ bugfix分支&#xff08;紧急补丁分支&…

微信设置快捷回复话术,快速回复!

微信上如何快速回复&#xff1f;其实是有个小技巧的 微信作为目前最流行的社交媒体平台之一&#xff0c;已经成为许多企业与用户之间沟通的重要渠道。当用户数量的增加和信息交流的频繁&#xff0c;如何提高回复效率就成了某部分人的问题。 微信上是没有快速回复的功能的&#…

315官方点赞!多燕瘦或将成酵素选购唯一标准

食用酵素及其衍生产品&#xff0c;是近年来国内主流电商平台的主要增长类目之一。在全球范围内&#xff0c;酵素的流行由来已久&#xff0c;其中在日本、北美、欧洲等发达国家和地区尤为风靡。据不完全统计&#xff1a;欧洲酵素市场规模约占全球酵素市场份额的40%以上&#xff…

Grafana监控大盘配置教程

1、新建大盘 2、输入指标和大盘名 若是Time series类型&#xff0c;则到此就可以看到数据&#xff1b;若是Table类型则进行下一步 3、修改大盘类型为Table 4、修改指标输出 Transformation functions&#xff1a;Transform data | Grafana documentation Filter by name——…

re学习(35)攻防世界-no-strings-attached(动调)

参考文章&#xff1a;re学习笔记&#xff08;28&#xff09;攻防世界-re-no-strings-attached_Forgo7ten的博客-CSDN博客 攻防世界逆向入门题之no-strings-attached_攻防世界 no-strings-attached_沐一 林的博客-CSDN博客 本人题解&#xff1a; 扔入Exepeinfo中查壳和其他信息…

预测性维护能为工厂带来什么改变?

数字化时代的到来&#xff0c;为制造业带来了前所未有的机遇和挑战。在数字化转型的浪潮中&#xff0c;预测性维护&#xff08;PredictiveMaintenance&#xff0c;简称PdM&#xff09;凭借其卓越的潜力&#xff0c;在提升设备效率、降低成本、优化生产等方面成为工厂的强有力助…

【0基础入门Python笔记】二、python 之逻辑运算和制流程语句

二、python 之逻辑运算和制流程语句 逻辑运算控制流程语句条件语句&#xff08;if语句&#xff09;循环结构&#xff08;for循环、while循环&#xff09;continue、break和pass关键字控制流程语句的嵌套以及elif 逻辑运算 Python提供基本的逻辑运算&#xff1a;不仅包括布尔运…

龙测面对面,一张图让你明白软件测试saas企业的功能布局

大家好&#xff0c;和大家认识也挺久了&#xff0c;好像也没有做过自我介绍。择日不如撞日&#xff0c;今天我们就好好聊聊吧。自我介绍分为了两个部分&#xff0c;上半部分是龙测科技的由来、梦想以及目前的成就&#xff1b;下半部分是龙测目前的产品功能框架。对产品功能感兴…

windows下redis服务启动及.bat文件中中redis服务的启动

windows windows下redis服务的启动 1、不配置环境变量 找到redis服务的安装目录进入命令行窗口并输入命令redis-server.exe redis.windows.conf2、配置环境变量 将redis安装目录配置在path环境变量中之后就可以在cmd窗口的任意位置输入redis-server命令就可以启动redis服务…

[测试报告] 爱搜Blog 自动化测试报告

目录 项目背景 项目功能 测试详情 一、设计测试用例 二、功能测试步骤结果 1. 登录页面 2. 个人博客页面 3. 博客详情页 4. 博客编辑页 三、自动化测试及测试结果 1. 测试环境 2. 登录测试用例&#xff1a; 3. 个人详情页测试用例&#xff1a; 4. 写博客并发布测试…

1849. 将字符串拆分为递减的连续值;1024. 视频拼接;1530. 好叶子节点对的数量

1849. 将字符串拆分为递减的连续值 核心思想:递归回溯题。和842. 将数组拆分成斐波那契序列的代码是差不多的&#xff0c;遇到拆分题首先想的就是dfs(index)表示从index开始拆分是否可以&#xff0c;然后去枚举拆分的end即可&#xff0c;我把这种题目归纳为拆分题&#xff0c;…