news 2026/5/1 1:16:05

[ROS实战] 零硬件成本调试户外导航:Python模拟GPS信号 + RViz加载高德地图实现“云”行走

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[ROS实战] 零硬件成本调试户外导航:Python模拟GPS信号 + RViz加载高德地图实现“云”行走

前言

在机器人户外导航开发中,我们经常面临一个尴尬的局面:人在室内写代码,机器人在吃灰。因为要测试 GPS 融合定位或地图显示功能,往往需要把机器人搬到室外空旷处。

有没有一种方法,能在室内、无硬件(甚至无机器人)的情况下,在 RViz 中模拟出一个 GPS 信号,并且能像玩游戏一样通过键盘(WASD)控制机器人在真实的高德卫星地图上行走?

本文将通过一个 Python 脚本配合rviz_satellite插件,带你实现这套零成本的仿真环境。


准备工作

  • 操作系统:Ubuntu 20.04

  • ROS 版本:Noetic

  • 所需插件rviz_satellite

1. 安装核心插件

我们需要一个能让 RViz 加载瓦片地图的插件。

Bash

sudo apt install ros-noetic-rviz-satellite

核心步骤一:编写 GPS + TF 模拟器

RViz 的显示逻辑依赖于TF (坐标变换),而地图插件依赖于GPS (/fix)。因此,我们的模拟脚本必须同时做两件事:

  1. 发布/fix话题:告诉地图插件“我在地球的哪个经纬度”,以便加载对应的瓦片图片。

  2. 发布 TF (map->base_link):告诉 RViz “机器人在地图坐标系下的 (x, y) 坐标”,以便让机器人模型动起来。

在你的工作空间(如~/catkin_ws/src/your_pkg/scripts/)下新建文件gps_simulator.py

Python

#!/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', anonymous=True) # 1. 发布 GPS 话题 (给地图插件用) self.pub = rospy.Publisher('/fix', NavSatFix, queue_size=10) # 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(target=self.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 瓦片服务。

  1. 启动 ROS:

    打开终端运行 roscore。

  2. 运行模拟器:

    打开新终端运行 python3 gps_simulator.py。

  3. 打开 RViz:

    打开新终端运行 rviz。

  4. 配置 RViz (关键)

    • Global Options -> Fixed Frame: 手动输入map。(注意:因为我们的脚本发布了 map->base_link 的 TF,所以这里必须填 map)。

    • Add: 点击左下角 Add,选择AerialMapDisplay

    • AerialMapDisplay 参数设置

      • Topic: 选择/fix

      • Map URL: 填入以下高德卫星图链接:

        Plaintext
        http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}
      • Zoom: 设置为1819。(设置太小如 0-10 可能导致加载不出图片)。

      • Blocks: 设置为4


效果展示与“云行走”

完成上述配置后,你应该能看到 RViz 的黑色背景瞬间变成了高清的卫星地图。

回到运行 Python 脚本的终端,按下键盘上的W/A/S/D

  • 现象 1:RViz 正中心的坐标轴(代表机器人)会开始移动。

  • 现象 2:随着机器人的移动,周围的地图瓦片会自动加载更新,不仅实现了“定位”,还实现了“地图跟随”。

进阶技巧:如何使用离线地图?

如果你需要在断网环境下演示,可以将 QGIS 导出的图片切片放在本地文件夹(例如/home/user/map/z/x/y.png),然后在该文件夹下运行:

Bash

python3 -m http.server 8000

最后将 RViz 中的 Map URL 改为http://127.0.0.1:8000/{z}/{x}/{y}.png即可完美欺骗插件加载离线图。


总结

通过本文的方法,我们解决了两个痛点:

  1. 解决了 RViz 报错:通过脚本广播 TF,解决了Fixed Frame [map] does not exist的经典错误。

  2. 解决了地图源问题:使用了高德地图 URL,无需翻墙,无需申请 Key,加载速度极快。

现在,你可以在温暖的室内,随意模拟机器人在城市街道、校区内的行驶轨迹,调试你的路径规划算法了!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 5:56:56

小白也能看懂的RLHF-PPO:原理篇

原文: https://mp.weixin.qq.com/s/8O7W8–x14-b1d3M9IS_3w LLM-RL往期文章推荐 小白也能看懂的RL-PPO 收藏!强化学习从入门到封神:5 本经典教材 8 大实战项目 7个免费视频,一站式搞定 小白也能看懂的RLHF:基础篇 在上一篇…

作者头像 李华
网站建设 2026/4/26 11:36:32

当AI成为你的生活搭档:让技术有温度地守护家庭

清晨六点,厨房的灯光自动亮起,恰到好处的亮度唤醒沉睡的身体;客厅的空气质量监测器悄悄启动新风系统,过滤掉夜间积聚的微尘;智能药盒准时响起轻柔提示,提醒母亲服用降压药。这不是科幻电影场景,…

作者头像 李华
网站建设 2026/4/17 0:22:02

cloudflare配合ikuai使用ipv6内网穿透

首先声明:文章是完全公开的,CSDN老是设置成VIP文章,我知道后都改回来了,也找不到客服怎么搞,坑。 感觉ipv6访问看自己家里的视频比ipv4快。所以就研究了两天终于把这个搞出来了。确实要比ipv4快。没有显卡硬解都感觉差…

作者头像 李华
网站建设 2026/4/18 15:24:49

华为ip-prefix

一. IP-Prefix的定义 IP-Prefix(IP前缀列表)是华为网络设备中用于精确匹配路由前缀的过滤工具。它通过前缀掩码范围的组合定义匹配规则,例如匹配192.168.1.0/24但排除192.168.1.0/26的子网。与传统ACL相比,其优势在于&#xff1a…

作者头像 李华
网站建设 2026/4/24 21:28:29

R语言在群落生态学分析中的全流程应用:从数据处理到模型构建

在森林生态学研究中,系统的结构、功能与稳定性是理解森林动态与生态服务的关键内容。随着研究手段的发展,R语言已成为该领域的重要分析工具,其丰富的统计与可视化功能支持对物种多样性、空间格局及生态过程的深入解析。通过多样性指数、排序分…

作者头像 李华
网站建设 2026/4/18 9:40:20

Qwen3-14B模型部署六大常见问题与解决方案

Qwen3-14B模型部署六大常见问题与解决方案 在AI从“演示可用”迈向“生产可靠”的关键阶段,越来越多企业选择将大语言模型(LLM)私有化部署到本地或专属云环境。而在这条通往智能自动化的路上,Qwen3-14B 正逐渐成为中型模型中的“黄…

作者头像 李华