网站制作的公,wordpress主题个人博客,2022年营业执照年检申报入口,电商平台取名字大全前言在机器人户外导航开发中#xff0c;我们经常面临一个尴尬的局面#xff1a;人在室内写代码#xff0c;机器人在吃灰。因为要测试 GPS 融合定位或地图显示功能#xff0c;往往需要把机器人搬到室外空旷处。有没有一种方法#xff0c;能在室内、无硬件#xff08;甚至无…前言在机器人户外导航开发中我们经常面临一个尴尬的局面人在室内写代码机器人在吃灰。因为要测试 GPS 融合定位或地图显示功能往往需要把机器人搬到室外空旷处。有没有一种方法能在室内、无硬件甚至无机器人的情况下在 RViz 中模拟出一个 GPS 信号并且能像玩游戏一样通过键盘WASD控制机器人在真实的高德卫星地图上行走本文将通过一个 Python 脚本配合rviz_satellite插件带你实现这套零成本的仿真环境。准备工作操作系统Ubuntu 20.04ROS 版本Noetic所需插件rviz_satellite1. 安装核心插件我们需要一个能让 RViz 加载瓦片地图的插件。Bashsudo apt install ros-noetic-rviz-satellite核心步骤一编写 GPS TF 模拟器RViz 的显示逻辑依赖于TF (坐标变换)而地图插件依赖于GPS (/fix)。因此我们的模拟脚本必须同时做两件事发布/fix话题告诉地图插件“我在地球的哪个经纬度”以便加载对应的瓦片图片。发布 TF (map-base_link)告诉 RViz “机器人在地图坐标系下的 (x, y) 坐标”以便让机器人模型动起来。在你的工作空间如~/catkin_ws/src/your_pkg/scripts/下新建文件gps_simulator.pyPython#!/usr/bin/env python3 # -*- coding: utf-8 -*- import rospy from sensor_msgs.msg import NavSatFix import tf import sys, select, termios, tty, threading, math # 配置区域 # 初始位置这里以西安长安大学附近为例 INIT_LAT 34.373056 INIT_LON 108.896667 INIT_ALT 0.0 # 移动步长每次按键移动 5 米 MOVE_STEP_M 5.0 # 频率 RATE 10.0 # 简易经纬度换算系数 (近似值) METERS_PER_LAT 111000.0 METERS_PER_LON 111000.0 * math.cos(math.radians(INIT_LAT)) class GpsSimNode: def __init__(self): rospy.init_node(gps_simulator, anonymousTrue) # 1. 发布 GPS 话题 (给地图插件用) self.pub rospy.Publisher(/fix, NavSatFix, queue_size10) # 2. 广播 TF 变换 (给 RViz 坐标显示用) self.tf_broadcaster tf.TransformBroadcaster() self.x 0.0 # 相对原点的东向距离 (米) self.y 0.0 # 相对原点的北向距离 (米) self.running True self.lock threading.Lock() print( GPS 模拟器已启动 ) print(f初始坐标: Lat {INIT_LAT}, Lon {INIT_LON}) print(控制方式: W(北) A(西) S(南) D(东) Q(退出)) def publish_loop(self): rate rospy.Rate(RATE) while not rospy.is_shutdown() and self.running: with self.lock: cx, cy self.x, self.y # 计算当前的经纬度 current_lat INIT_LAT (cy / METERS_PER_LAT) current_lon INIT_LON (cx / METERS_PER_LON) # A. 发布 GPS msg NavSatFix() msg.header.stamp rospy.Time.now() msg.header.frame_id base_link msg.latitude current_lat msg.longitude current_lon msg.altitude INIT_ALT self.pub.publish(msg) # B. 发布 TF (map - base_link) # 这让 RViz 知道机器人在哪里从而消除 Fixed Frame [map] does not exist 报错 self.tf_broadcaster.sendTransform( (cx, cy, 0.0), tf.transformations.quaternion_from_euler(0, 0, 0), rospy.Time.now(), base_link, map ) rate.sleep() def get_key(self): # 非阻塞键盘读取 tty.setraw(sys.stdin.fileno()) rlist, _, _ select.select([sys.stdin], [], [], 0.1) key sys.stdin.read(1) if rlist else termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings) return key def run(self): t threading.Thread(targetself.publish_loop) t.start() try: while not rospy.is_shutdown(): key self.get_key() if key: with self.lock: if key w: self.y MOVE_STEP_M elif key s: self.y - MOVE_STEP_M elif key a: self.x - MOVE_STEP_M elif key d: self.x MOVE_STEP_M elif key in [q, \x03]: self.running False break print(f\r当前偏移: X{self.x:.1f}m, Y{self.y:.1f}m , end) finally: self.running False t.join() if __name__ __main__: settings termios.tcgetattr(sys.stdin) try: GpsSimNode().run() except rospy.ROSInterruptException: pass finally: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)(别忘了给脚本加权限chmod x gps_simulator.py)核心步骤二在 RViz 中接入高德地图国内网络环境下Google Maps 经常无法加载而高德地图AutoNavi提供了极其稳定的 XYZ 瓦片服务。启动 ROS打开终端运行 roscore。运行模拟器打开新终端运行 python3 gps_simulator.py。打开 RViz打开新终端运行 rviz。配置 RViz (关键)Global Options - Fixed Frame: 手动输入map。注意因为我们的脚本发布了 map-base_link 的 TF所以这里必须填 map。Add: 点击左下角 Add选择AerialMapDisplay。AerialMapDisplay 参数设置Topic: 选择/fix。Map URL: 填入以下高德卫星图链接Plaintexthttp://webst01.is.autonavi.com/appmaptile?style6x{x}y{y}z{z}Zoom: 设置为18或19。设置太小如 0-10 可能导致加载不出图片。Blocks: 设置为4。效果展示与“云行走”完成上述配置后你应该能看到 RViz 的黑色背景瞬间变成了高清的卫星地图。回到运行 Python 脚本的终端按下键盘上的W/A/S/D现象 1RViz 正中心的坐标轴代表机器人会开始移动。现象 2随着机器人的移动周围的地图瓦片会自动加载更新不仅实现了“定位”还实现了“地图跟随”。进阶技巧如何使用离线地图如果你需要在断网环境下演示可以将 QGIS 导出的图片切片放在本地文件夹例如/home/user/map/z/x/y.png然后在该文件夹下运行Bashpython3 -m http.server 8000最后将 RViz 中的 Map URL 改为http://127.0.0.1:8000/{z}/{x}/{y}.png即可完美欺骗插件加载离线图。总结通过本文的方法我们解决了两个痛点解决了 RViz 报错通过脚本广播 TF解决了Fixed Frame [map] does not exist的经典错误。解决了地图源问题使用了高德地图 URL无需翻墙无需申请 Key加载速度极快。现在你可以在温暖的室内随意模拟机器人在城市街道、校区内的行驶轨迹调试你的路径规划算法了