You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WSL中ROS节点实时单坐标点散点图及背景图全屏适配问题

解决方案

核心问题修复说明

1. 仅显示最新坐标点(解决卡顿)

原代码每次收到坐标就新建一个散点,历史点持续堆积导致渲染卡顿。我们改为初始化单个散点对象,仅更新其坐标数据,避免重复创建图形元素;同时用线程锁保证多线程下的变量安全。

2. 全屏适配修复

原代码混用plt.show()和Tkinter嵌入,导致窗口逻辑冲突。我们直接基于Tkinter实现全屏,让matplotlib画布填充整个窗口,同时调整背景图的显示逻辑,使其自适应窗口大小。

修改后的完整代码

from Tkinter import Canvas
import Tkinter as Tk
import rospy
from std_msgs.msg import String
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from threading import Thread, Lock
import numpy as np

# 线程锁,保证坐标更新的线程安全
coord_lock = Lock()
# 存储最新坐标
latest_x, latest_y = 0, 0
# 散点对象,用于后续更新
scatter_point = None

def callback(data):
    global latest_x, latest_y
    received = data.data.split(',')
    x = int(float(received[0]))
    y = int(float(received[1]))
    
    # 线程安全更新坐标
    with coord_lock:
        latest_x, latest_y = x, y

def listener():
    rospy.Subscriber('first', String, callback)
    rospy.spin()

def animate(i):
    global scatter_point
    # 更新散点坐标
    with coord_lock:
        if scatter_point is not None:
            scatter_point.set_offsets([[latest_x, latest_y]])
    return [scatter_point]

def visual():
    global scatter_point
    root = Tk.Tk()
    root.title("Realtime plot")
    
    # 设置窗口全屏,按ESC退出
    root.attributes('-fullscreen', True)
    root.bind('<Escape>', lambda e: root.destroy())
    
    # 加载背景图
    img = plt.imread("back.jpg")
    fig, ax = plt.subplots()
    
    # 显示背景图,取消固定宽高比让图自适应窗口
    ax.imshow(img, extent=[0, 17947, -200, 5330], aspect='auto')
    # 初始化散点(初始坐标可按需调整)
    scatter_point = ax.scatter(latest_x, latest_y, color='red', s=50)
    
    # 将matplotlib画布嵌入Tkinter窗口并填充全屏
    plotcanvas = FigureCanvasTkAgg(fig, root)
    plotcanvas.get_tk_widget().pack(fill=Tk.BOTH, expand=True)
    
    # 启动动画,blit=True仅更新变化区域提升效率
    ani = FuncAnimation(fig, animate, interval=100, blit=True)
    
    Tk.mainloop()

# 启动线程
t1 = Thread(target=visual)
t1.start()
listener()
t1.join()

关键改动点

  • 新增coord_lock线程锁:解决ROS回调线程和matplotlib动画线程的坐标变量读写冲突
  • 单个散点对象复用:仅初始化一次散点,后续通过set_offsets更新坐标,避免图形元素堆积
  • 移除plt.show():取消独立matplotlib窗口,完全由Tkinter管理窗口逻辑
  • Tkinter全屏设置:通过attributes('-fullscreen', True)实现全屏,绑定ESC键快速退出
  • 画布自适应窗口:pack(fill=Tk.BOTH, expand=True)让matplotlib画布随窗口拉伸
  • aspect='auto':取消背景图固定宽高比,适配窗口大小
  • blit=True:动画仅刷新变化区域,降低渲染压力

内容的提问来源于stack exchange,提问作者rebrid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 20:40:31