47.在ROS中实现global planner(3)

news2024/11/15 2:12:28

接着之前45.在ROS中实现global planner(1)和46.在ROS中实现global planner(2)的铺垫,在ROS中实现AStar Global Planner

1. planner package

  • 照着之前的模板,修改下名称
git clone -b https://gitee.com/pibot/sample_global_planner.git astar_global_planner

再替换下所有的sample_global_planner–>astar_global_planner

  • 基于这个我们新增之前的astar算法
    拷贝astar_planner.h 和astar_planner.cpp 分别至includesrc目录
  • 修改CMakeLists.txt
    • 添加编译
    add_library(${PROJECT_NAME}
      src/planner_node.cpp
      src/astar_planner.cpp  # 新增
    )
    
    • 添加opencv的依赖
    find_package(catkin REQUIRED
    COMPONENTS
        costmap_2d
        OpenCV)
    
    • c++11支持
      使用了c++11 cmake打开配置
    add_compile_options(-std=c++11) 
    

直接编译试下
catkin_make -DCATKIN_WHITELIST_PACKAGES=astar_global_planner
头文件报错,稍微修改下
#include "astar_global_planner/astar_planner.h"

2. 规划实现

前面加入了编译,下面我们具体新增其的使用

2.1 添加AStarPlanner

  • 把之前实现好的AStarPlanner 添加为GlobalPlanner的一个成员

      std::unique_ptr<AStarPlanner> planner_; // 这里我们指定为指针
    
  • 初始化接口添加对其的实例化

      planner_ = std::unique_ptr<AStarPlanner>(new AStarPlanner());
    

2.2 接口调用

AStarPlanner 主要的接口就是

bool Plan(const Mat& cost_map, const Point& start_point, const Point& end_point, std::vector<Point>& path, PlannerAction planner_action);

主要接收一个地图参数cost_map, 一个起点start_point,一个终点end_point, 输出为路径path

planner_action为回调函数 之前调试显示用,这里用不到, 传入nullptr

  • 地图

地图参数在GlobalPlannerinitialize接口有指定,我们只需要在这里保存下来,保存至成员,后续函数中使用

void GlobalPlanner::initialize(std::string name, costmap_2d::Costmap2DROS* costmap_ros) {
  costmap_ = costmap_ros->getCostmap();

  int nx = costmap_->getSizeInCellsX(), ny = costmap_->getSizeInCellsY();
  double resolution = costmap_->getResolution();

  cv::Mat costmap_mat = cv::Mat(costmap_->getSizeInCellsY(), costmap_->getSizeInCellsX(), CV_8UC1, costmap_->getCharMap());
  costmap_mat_ = costmap_mat.clone();  // costmap_mat_保存地图的拷贝
}
  • 起点&终点
    规划接口中传入了2个参数分别是起点和终点,但需要注意传入的点的坐标系为世界坐标系,并非地图的坐标,所以需要做转换,initialize传入参数costmap_ros带有转换接口worldToMap直接调用即可,如下
  unsigned int start_x_i, start_y_i, goal_x_i, goal_y_i;

  double wx = start.pose.position.x;
  double wy = start.pose.position.y;
  costmap_->worldToMap(wx, wy, start_x_i, start_y_i);

  wx = goal.pose.position.x;
  wy = goal.pose.position.y;

  costmap_->worldToMap(wx, wy, goal_x_i, goal_y_i)
  • 执行规划
    只需要调用AStarPlannerPlan接口,传入相应的参数即可
  std::vector<Point> path;
  bool vaild = planner_->Plan(costmap_mat_, {start_x_i, start_y_i}, {goal_x_i, goal_y_i}, path, nullptr);
  • 输出路径
    同起点&终点相反,这里输出路径保存的是地图坐标,所有需要转换到世界坐标返回,同样使用costmap_ros的下mapToWorld接口即可
    另外AStarPlanner Plan接口输出的路径是从终点到起点的,这里需要反序列后输出
bool GlobalPlanner::makePlan(const geometry_msgs::PoseStamped& start,
                             const geometry_msgs::PoseStamped& goal,
                             std::vector<geometry_msgs::PoseStamped>& plan) {
  ...

  geometry_msgs::PoseStamped pose = goal;

  // 使用path反向迭代器循环
  for (auto it = path.rbegin(); it != path.rend(); it++) {
    costmap_->mapToWorld(it->x, it->y, pose.pose.position.x, pose.pose.position.y);
    plan.push_back(pose);
  }
  
  // plan 即为需要返回和pub的路径
  ....
}

3. 测试

  • 修改move_base_params.yaml中的base_global_planner

    base_global_planner: astar_global_planner/GlobalPlanner
    
  • 启动模拟器
    pibot_simulator

  • 查看插件是否加载

    ❯ rosparam get /move_base/base_global_planner
    astar_global_planner/GlobalPlanner
    
  • 打开rviz查看
    pibot_view
    test plan

可以看出来AStar Global Planner已经生效了,规划路径也出来了, 很不幸的是local planner一直无法正常运行,显然这个路径规划的太贴近障碍物。导致规划的结果无法在实际机器人场景使用, 后续我们看看如何做优化。

4. 优化

4.1 规划优化

我们的A* 算法没有考虑到障碍无的距离,导致可能紧挨着障碍物,我们需要在启发函数新增里障碍物的距离值,以使得规划路径尽量远离障碍物。

ROS中的地图是cost map,所谓cost map也就是每个grid点有自己的cost, 如官方的这张图片
costmap

简单的说在ROS中,未知区域值255, 障碍物为254,其他就是远离障碍物就越越小

  • 这样我们在计算H的函数新增个参数,同时添加相应的weight

    float Point2PointPlanner::CalcH(const Point& current_point, const Point& end_point) {
      ...
      return min_diff * kCornerCost + (max_diff - min_diff) * kLineCost;
    }
    

    改为

    float Point2PointPlanner::CalcH(const Point& current_point, const Point& end_point, float cost) {
      ...
      return min_diff * kCornerCost + (max_diff - min_diff) * kLineCost + cost * kCost;
      }
    
  • 计算时传入每个gridcost

    ...
      open_list_.emplace(start_point, 0, CalcH(start_point, end_point, cost_map_.at<unsigned char>(start_point.y, start_point.x)));
    
    ...`
    
      all_grid_[index].Update(neighbor, point, G, CalcH(neighbor, end_point, cost_map_.at<unsigned char>(neighbor.y, neighbor.x)));
    ...
    

再次编译测试,结果如下图,可以看到规划的路径在道路中间,并且local planner可以正常工作。`
在这里插入图片描述

4.2 路径优化

可以看到,规划的路径是还存在瑕疵,路径是锯齿状的,对local planner的控制有一定影响,我们可以添加平滑处理,使得路径更为平滑
参考ROS:一种简单的基于global_planner的全局路径优化方法得到效果如下
优化后路径

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

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

相关文章

OpenCV 图像金字塔算子

本文是OpenCV图像视觉入门之路的第14篇文章&#xff0c;本文详细的介绍了图像金字塔算子的各种操作&#xff0c;例如&#xff1a;高斯金字塔算子 、拉普拉斯金字塔算子等操作。 高斯金字塔中的较高级别&#xff08;低分辨率&#xff09;是通过先用高斯核对图像进行卷积再删除偶…

大疆车载更新产品矩阵,覆盖从主动安全到城区领航的全场景

新年智驾供应商的攻势&#xff0c;也像车企一样猛烈。大疆车载近期趁着官网更新&#xff0c;对外公布了梳理后的智驾方案序列&#xff0c;覆盖8大功能产品&#xff1a;主动安全、行车辅助、泊车辅助、记忆泊车、记忆行车、跨层记忆泊车、领航高速、领航城区。需要关注的是&…

金融帝国实验室(Capitalism Lab)《官方中文社群抽奖规则》(修订)

★修 订 说 明★ 为进一步完善社群决策制定程序&#xff0c;提高抽奖活动公平化、丰富化水平&#xff0c;切实提升抽奖活动质量&#xff0c;现对《官方中文社群抽奖规则》进行修订&#xff08;第四次&#xff09;。 ————————————— ◎〖本次修订内容〗&#xf…

C++ 浅谈之 AVL 树和红黑树

C 浅谈之 AVL 树和红黑树 HELLO&#xff0c;各位博友好&#xff0c;我是阿呆 &#x1f648;&#x1f648;&#x1f648; 这里是 C 浅谈系列&#xff0c;收录在专栏 C 语言中 &#x1f61c;&#x1f61c;&#x1f61c; 本系列阿呆将记录一些 C 语言重要的语法特性 &#x1f3…

可靠、安全、稳定,开源高质量项目 | 亚马逊的开源文化

亚马逊的领导力准则是亚马逊文化的核心&#xff0c;它如同亚马逊的 DNA 融入贯穿每一个重要决策&#xff0c;深深影响着每一位亚麻人、影响着每一位亚马逊的客户、合作伙伴以及每一位亚马逊云科技的构建者。同时&#xff0c;亚马逊的领导力准则对亚马逊与开源的互动方式也产生着…

(原创)不小心禁用或者卸载Kotlin插件的解决方法

问题 之前因为kotlin版本的一些问题&#xff0c;不小心禁用了kotlin插件 等到再重启Android Studio&#xff0c;就发现进不去了 后来在网上找到方法解决了&#xff0c;但是某一天 又脑子一热&#xff0c;直接把Kotlin插件给卸载了&#xff0c;这下直接玩大发了 花了一点时间才…

Springboot 使用quartz 定时任务 增删改查

前段时间公司项目用到了 定时任务 所以写了一篇定时任务的文章 &#xff0c;浏览量还不错 &#xff0c; Springboot 整合定时任务 ) 所以就准备写第二篇&#xff0c; 如果你是一名Java工程师&#xff0c;你也可以会看到如下的页面 &#xff0c;去添加定时任务 定时任务展示 :…

linux学习笔记 超详细 0基础(下)shell

shell是一个命令解释器&#xff0c;为我们提供了交互式的文本控制台界面&#xff0c;我们可以通过终端控制台来输入命令&#xff0c;由shell解释并交给linux内核执行。Shell是一个解释器&#xff0c;Unix下的Bourne Shell命令解释器的加强版Bourne Again Shell &#xff0c;bas…

甘特图:项目管理工具,轻松简化工作流程

项目规模越大&#xff0c;管理就越复杂&#xff0c;有时候甚至一个项目经理需要管理多个项目&#xff0c;当多个项目、多条任务同时进行&#xff0c;项目所涉及的范围广&#xff0c;内容越来越复杂&#xff0c;使得项目越难以把控&#xff0c;好的管理工具&#xff0c;可以提升…

2023美赛C题:Wordle筛选算法

Wordle 规则介绍 Wordle 每天会更新一个5个字母的单词&#xff0c;在6次尝试中猜出单词就算成功。每个猜测必须是一个有效的单词&#xff08;不能是不能组成单词的字母排列&#xff09;。 每次猜测后&#xff0c;字母块的颜色会改变&#xff0c;颜色含义如下&#xff1a; 程…

Unity导出WebGL工程,并部署本地web服务器

WebGL打包 设置修改 在Build Settings->PlayerSettings->Other Settings->Rendering 将Color Space 设置为Gamma 将Lightmap Encoding 设置为NormalQuality 在Build Settings->PlayerSettings->Publishing Settings 勾选Decompression Fallback 打包 完成配…

有这几个表现可能是认知障碍前兆

我国目前对于认知障碍的认知率、就诊率、诊断率很低&#xff0c;然而认知障碍如果能在早期发现&#xff0c;并及时治疗&#xff0c;生活质量会有效提高&#xff0c;缓解家属的精神和经济负担。所以&#xff0c;认知障碍的前兆一定要了解。1.记忆力减退&#xff0c;一周内的重要…

【Spring】@Value注入配置文件 application.yml 中的值失败怎么办

本期目录一、 问题背景二、 问题原因三、 解决方法一、 问题背景 今天碰到的问题是用 Value 注解无法注入配置文件 application.yml 中的配置值。 检查过该类已经交给 Spring 容器管理了&#xff0c;即已经在类上加了 Configuration 和 ConfigurationProperties(prefix &quo…

UnityEditor编辑器扩展自己实现了一遍SceneView的镜头移动

基本实现由于最近一个星期都比较魔怔《天际线》&#xff0c;突然开始要工作了&#xff0c;用Editor好像突然没了按键反而不习惯就是要实现一个点击AWSD&#xff0c;能方便编辑地图的功能其实大可不必自己写代码本身Unity自带的&#xff0c;飞跃模式已经包含&#xff08;按鼠标右…

抽象工厂模式(Abstract Factory Pattern)

1.抽象工厂模式定义: 抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口&#xff0c;无需指定它们具体的类 2.抽象工厂模式适用场景: 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量…

ONLYOFFICE中的chatGPT是怎样提升工作效率的

几乎一夜之间chatGPT火遍国内外网络&#xff0c;作为一个总是努力提高工作效率并在一天内完成更多工作的人&#xff0c;我很高兴发现 ONLYOFFICE添加了ChatGPT — 一个人工智能驱动的聊天机器人&#xff0c;可以帮助您管理时间、设定目标并改善您的个人和职业生活。 ONLOYOFFIC…

Allegro172版本无法低亮颜色的原因和解决办法

Allegro172版本无法低亮颜色的原因和解决办法 用Allegro版本做PCB设计的时候,高亮是使用非常频繁的功能,低亮已经高亮的对象也是使用较为频繁的。 在用172版本时会出现无法低亮的情况,如下图 使用Dehilight命令无法低亮器件,如何解决,具体操作步骤如下 点击Display选择De…

Python:每日一题之剪邮票(BFS全排列)

如【图1.jpg】, 有12张连在一起的12生肖的邮票。 现在你要从中剪下 5 张来&#xff0c;要求必须是连着的。 &#xff08;仅仅连接一个角不算相连&#xff09; 比如&#xff0c;【图2.jpg】&#xff0c;【图3.jpg】中&#xff0c;粉红色所示部分就是合格的剪取。 请你计算&…

redis的安装步骤及前台,后台redis服务启动

redis的安装步骤1. 官网下载安装包2. 使用Xftp将安装包传输到Linux的opt目录下3. 使用Xshell连接Linux主机进行redis的安装安装目录说明4. redis 服务启动的两种方式4.1 前台启动4.2 后台启动1. 官网下载安装包 首先&#xff0c;我们进入到redis的官网: https://redis.io/down…

代码随想录算法训练营第三十一天 | 贪心专题-理论基础,455.分发饼干,376. 摆动序列,53. 最大子序和

一、参考资料理论基础https://programmercarl.com/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 分发饼干https://programmercarl.com/0455.%E5%88%86%E5%8F%91%E9%A5%BC%E5%B9%B2.html 摆动序列https://programmercarl.com/0376.%E6%91%86…