nav2_gps_waypoint_follower_demo 不能在ros2 humble中直接使用的解决方法

GIT上的nav2_gps_waypoint_follower_demo是基于ros-iron编写的,其中followGpsWaypoints(wps) service只能在Iron上使用。

解决方法:

第一步:interactive_waypoint_follower.py修改为如下代码:

import rclpy
from rclpy.node import Node
from nav2_simple_commander.robot_navigator import BasicNavigator
from geometry_msgs.msg import PointStamped
from nav2_gps_waypoint_follower_demo.utils.gps_utils import latLonYaw2Geopose
from nav2_msgs.action import FollowWaypoints
from geometry_msgs.msg import PoseStamped
from robot_localization.srv import FromLLclass InteractiveGpsWpCommander(Node):"""ROS2 node to send gps waypoints to nav2 received from mapviz's point click publisher"""def __init__(self):super().__init__(node_name="gps_wp_commander")self.navigator = BasicNavigator("basic_navigator")self.mapviz_wp_sub = self.create_subscription(PointStamped, "/clicked_point", self.mapviz_wp_cb, 1)self.localizer = self.create_client(FromLL,  '/fromLL')while not self.localizer.wait_for_service(timeout_sec=1.0):self.get_logger().info('Service not available, waiting again...')self.client_futures = []self.get_logger().info('Ready for waypoints...')def mapviz_wp_cb(self, msg: PointStamped):"""clicked point callback, sends received point to nav2 gps waypoint follower if its a geographic point"""if msg.header.frame_id != "wgs84":self.get_logger().warning("Received point from mapviz that ist not in wgs84 frame. This is not a gps point and wont be followed")returnwps = [latLonYaw2Geopose(msg.point.y, msg.point.x)]for wp in wps:self.req = FromLL.Request()self.req.ll_point.longitude = wp.position.longitudeself.req.ll_point.latitude = wp.position.latitudeself.req.ll_point.altitude = wp.position.altitudeself.get_logger().info("Waypoint added to conversion queue...")self.client_futures.append(self.localizer.call_async(self.req))def command_send_cb(self, future):self.resp = PoseStamped()self.resp.header.frame_id = 'map'self.resp.header.stamp = self.get_clock().now().to_msg()self.resp.pose.position = future.result().map_pointself.navigator.goToPose(self.resp)def spin(self):while rclpy.ok():rclpy.spin_once(self)incomplete_futures = []for f in self.client_futures:if f.done():self.client_futures.remove(f)self.get_logger().info("Following converted waypoint...")self.command_send_cb(f)else:incomplete_futures.append(f)self.client_futures = incomplete_futuresdef main():rclpy.init()gps_wpf = InteractiveGpsWpCommander()gps_wpf.spin()if __name__ == "__main__":main()

logged_waypoint_follower.py改为如下代码:

import rclpy
from nav2_simple_commander.robot_navigator import BasicNavigator
import yaml
from ament_index_python.packages import get_package_share_directory
import os
import sys
import time
from robot_localization.srv import FromLL
from rclpy.node import Node
from nav2_gps_waypoint_follower_demo.utils.gps_utils import latLonYaw2Geopose
from nav2_msgs.action import FollowWaypoints
from geometry_msgs.msg import PoseStampedclass YamlWaypointParser:"""Parse a set of gps waypoints from a yaml file"""def __init__(self, wps_file_path: str) -> None:with open(wps_file_path, 'r') as wps_file:self.wps_dict = yaml.safe_load(wps_file)def get_wps(self):"""Get an array of geographic_msgs/msg/GeoPose objects from the yaml file"""gepose_wps = []for wp in self.wps_dict["waypoints"]:latitude, longitude, yaw = wp["latitude"], wp["longitude"], wp["yaw"]gepose_wps.append(latLonYaw2Geopose(latitude, longitude, yaw))return gepose_wpsclass GpsWpCommander(Node):"""Class to use nav2 gps waypoint follower to follow a set of waypoints logged in a yaml file"""def __init__(self, wps_file_path):super().__init__('minimal_client_async')self.navigator = BasicNavigator("basic_navigator")self.wp_parser = YamlWaypointParser(wps_file_path)self.localizer = self.create_client(FromLL,  '/fromLL')while not self.localizer.wait_for_service(timeout_sec=1.0):self.get_logger().info('service not available, waiting again...')def start_wpf(self):"""Function to start the waypoint following"""self.navigator.waitUntilNav2Active(localizer='controller_server')wps = self.wp_parser.get_wps()wpl = []for wp in wps:self.req = FromLL.Request()self.req.ll_point.longitude = wp.position.longitudeself.req.ll_point.latitude = wp.position.latitudeself.req.ll_point.altitude = wp.position.altitudelog = 'long{:f}, lat={:f}, alt={:f}'.format(self.req.ll_point.longitude, self.req.ll_point.latitude, self.req.ll_point.altitude)self.get_logger().info(log)self.future = self.localizer.call_async(self.req)rclpy.spin_until_future_complete(self, self.future)self.resp = PoseStamped()self.resp.header.frame_id = 'map'self.resp.header.stamp = self.get_clock().now().to_msg()self.resp.pose.position = self.future.result().map_pointlog = 'x={:f}, y={:f}, z={:f}'.format(self.future.result().map_point.x, self.future.result().map_point.y, self.future.result().map_point.z)self.get_logger().info(log)self.resp.pose.orientation = wp.orientationwpl += [self.resp]self.navigator.followWaypoints(wpl)print("wps completed successfully")def main():rclpy.init()# allow to pass the waypoints file as an argumentdefault_yaml_file_path = os.path.join(get_package_share_directory("node"), "config", "demo_waypoints.yaml")if len(sys.argv) > 1:yaml_file_path = sys.argv[1]else:yaml_file_path = default_yaml_file_pathgps_wpf = GpsWpCommander(yaml_file_path)gps_wpf.start_wpf()if __name__ == "__main__":main()

第二步:除了上述代码需要修改,nav2_no_map_params.yaml也需要修改,该文件中bt_navigator节点下的内容改为nav2 humble里面默认的部分,另外,建议global_costmap中的width/height改大,例如从50改到500,不然容易出现超出global_costmap范围的提示。

参考链接(tks LuukBerkel ):nav2_gps_waypoint_follower_demo does not work on ros2 humble???! · Issue #77 · ros-planning/navigation2_tutorials · GitHub

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

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

相关文章

前端语义化标签及实例

常用的语义化标签的以下几种&#xff1a; header、nav、article、section、aside、footer、abbr、dfn、address、del、ins、pre、meter、progress <header> 定义文章的页眉信息 <header><h1>我的网站标题</h1><nav><ul><li><a …

windows 字符编码

LPSTR char* LPCSTR const char* LPWSTR wchar_t* LPCWSTR const wchar_t* LPTSTR TCHAR* LPCTSTR const TCHAR*STD_OUTPUT_HANDLE 标准输出句柄 STD_INTPUT_HANDLE 标准输入句柄 STD_ERROR_HANDLE 标准错误句柄 windows 使用的是utf-16 linux 使用的是utf-8 wch…

4. 使用zap替换gin框架默认的日志并配置日志切割

文章目录 一、gin默认的中间件二、基于zap的中间件三、在gin项目中使用zap 本文将介绍在基于gin框架开发的项目中如何配置并使用zap来接收gin框架默认的日志以及如何配置日志切割。 我们在基于gin框架开发项目时通常都会选择使用专业的日志库来记录项目中的日志&#xff0c;go…

leancloud云存储如何接入App Inventor 2?

提问&#xff1a;leancloud如何应用到App Inventor 2&#xff1f; LeanCloud 能够高效存取海量级 JSON 对象、二进制文件、地理位置等数据。其内置的行级 ACL 权限控制&#xff0c;以及通用的用户及角色管理体系&#xff0c;可以快速实现安全而灵活的数据访问。 根据官方文档&a…

如何通过考核提高酒店人员工作积极性

近年来&#xff0c;随着旅游行业的快速发展&#xff0c;也带动了酒店业的兴盛。酒店的经营效益不仅受益于旅游业&#xff0c;同时也受制于旅游行业。由于旅游业存在明显的季节性差异&#xff0c;旅游旺季客流量多、淡季客流量少&#xff0c;造成人员忙闲不均的问题。酒店行业也…

Android岗面试12家大厂成功跳槽,万字长文

都说程序员是一个青春饭&#xff0c;而我也不知不觉进入行业七年多了&#xff0c;自己也马上要进入而立之年了。都说30岁是每个程序员必会经历的一道坎&#xff0c;而自己也快到要面对这个坎了&#xff0c;我时常会想我能不能跨个这道坎。 于是请教了一些年过30还发展很好的前辈…

【Python】2. 基础语法(1)

常量和表达式 我们可以把 Python 当成一个计算器, 来进行一些算术运算. 注意: print 是一个 Python 内置的 函数, 这个稍后详细介绍. 可以使用 - * / ( ) 等运算符进行算术运算. 先算乘除, 后算加减. 运算符和数字之间, 可以没有空格, 也可以有多个空格. 但是一般习惯上写一…

设计模式: 模板方法模式

文章目录 一、什么是模板方法模式二、模板方法模式结构三、优点 一、什么是模板方法模式 模板方法模式&#xff08;Template Method Pattern&#xff09;是一种行为设计模式&#xff0c;它定义了一个操作中的算法骨架&#xff0c;将一些步骤延迟到子类中实现。这样可以使得子类…

2024/3/5打卡最长上升子序列**----线性DP,贪心,单调栈

目录 题目&#xff1a; DP分析&#xff1a; 代码&#xff1a; 3.6更新 贪心 第一个思考方式 先上代码&#xff1a; 解析&#xff1a; 贪心 第二个思考方式 &#xff08;与上面的思路差不多&#xff0c;但是换了个角度&#xff09; 思路&#xff1a; 代码&#xff1a; …

freeRTOS day1

总结keil5下载代码和编译代码需要注意的事项 选择合适的微控制器型号&#xff1a;确保你选择的控制器型号与你的项目中实际使用的硬件相匹配。 配置项目设置&#xff1a;正确设置目标芯片的时钟频率、内存大小等参数&#xff0c;以确保编译出的代码能够在硬件上正常运行。 添…

qt 语音引擎 QTextToSpeech Microsoft SAPI

QT中语音播报的代码 在QT中实现语音播报可以使用QTextToSpeech类&#xff0c;具体代码如下&#xff1a; #include <QCoreApplication> #include <QTextToSpeech> #include <QDebug>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 创…

数据结构->链表分类与oj(题),带你提升代码好感

✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;橘橙黄又青-CSDN博客 1.&#x1f34e;链表的分类 前面我们学过顺序表&#xff0c;顺序表问题&#xff1a; …

程序员如何选择职业赛道

程序员如何选择职业赛道&#xff1f; 程序员的职业赛道就像是一座迷宫&#xff0c;有前端的美丽花园&#xff0c;后端的黑暗洞穴&#xff0c;还有数据科学的神秘密室。你准备好探索这个充满挑战和机遇的迷宫了吗&#xff1f;快来了解如何选择职业赛道吧&#xff01; 方向一&a…

大唐杯学习笔记:Day5

1.1 小区搜索 搜索流程 PLMN选择 自动模式&#xff1a;UE根据NAS的请求或自主地向NAS报告可用的PLMN 手动模式&#xff1a;通过手动选择一个可用的VPLMN获取正常服务 频点选择 5G NR中,3GPP主要指定了两个频率范围,一个是6GHZ以下,另一个是毫米波,分别称之为FR1和FR2。 N…

AIOps实践中常见的挑战:故障根因与可观测性数据的割裂

运维的挑战与责任 在数字化时代&#xff0c;运维团队面临的挑战前所未有。他们不仅要确保系统的高可用性和高性能&#xff0c;还要快速响应并解决故障&#xff0c;以减少对业务的影响。在这种背景下&#xff0c;运维团队急需工具和技术&#xff0c;能够帮助他们提高效率&#…

一文解释python中的实例方法,类方法和静态方法作用和区别是啥?该如何使用

我们都知道 &#xff0c;python类中有三种常见的方法 &#xff0c;分别是实例方法 &#xff0c;类方法和静态方法 。那么这几个方法到底有什么作用 &#xff1f; 它们之间有什么区别 &#xff1f;该如何使用 &#xff1f; 带着这些问题 &#xff0c;下面我们就来了解下这三种方…

1688商品详情数据采集,工程数据采集丨店铺数据采集丨商品详情数据采集

1688是中国的一个大型B2B电子商务平台&#xff0c;主要用于批发和采购各种商品。对于需要从1688上获取商品详情数据、工程数据或店铺数据的用户来说&#xff0c;可以采用以下几种常见的方法&#xff1a; 官方API接口&#xff1a;如果1688提供了官方的API接口&#xff0c;那么可…

【高效开发工具系列】vimdiff简介与使用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

米哈游排名首超腾讯,登顶榜首 !!!

米哈游排名首超腾讯&#xff0c;登顶榜首 &#xff01;&#xff01;&#xff01; 大家好&#xff0c;我是銘&#xff0c;全栈开发程序员。 近日&#xff0c;第三方机构 data.ai 公布 2023 年中国游戏厂商及应用出海收入 30 强。 其中米哈游超越腾讯&#xff0c;首次登顶年度…

我的知识脉络

O、自我介绍 一、技术选型 前端框架&#xff1a;vue2、vue3、React 老版本及 hooks版本&#xff1b; SSR框架&#xff1a;next&#xff1b; 微前端框架&#xff1a;Single-SPA、qiankun&#xff08;乾坤&#xff09;、无界、McroApp&#xff1b; 跨端方案&#xff1a;RN、webA…