rospy节点一边接收topic,一边将topic数据可视化

如果想要matplotlib动态更新画图,只能将matplotlib放在主线程中,如果放进子线程,就会报这个错

复制代码
ValueError: set_wakeup_fd only works in main thread

但是如果要订阅ros的topic,主线程会被阻塞,matplotlib无法动态更新。

因此,通过将matplotlib嵌入tkinter中,实现一边订阅topic,一边动态更新画图

python 复制代码
import math
import rospy
import message_filters
import tkinter as tk
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from my_pkg.msg import MyArrayMessage


class ROS_Tkinter_App:
    def __init__(self, master):
        self.master = master
        master.title("ROS Tkinter App")

        # Matplotlib setup for scatter plot
        self.figure = Figure(figsize=(10, 8), dpi=100)
        self.scatter_plot = self.figure.add_subplot(111)
        self.scatter_plot.set_title('Scatter Plot')
        self.canvas = FigureCanvasTkAgg(self.figure, master=master)
        self.canvas.get_tk_widget().pack()

        # ROS Initialization
        rospy.init_node('ros_tkinter_app', anonymous=True)

        # Define subscribers for the two topics
        sub_topic1 = message_filters.Subscriber("/global_path", MyArrayMessage)
        sub_topic2 = message_filters.Subscriber("/vehicle_position", MyArrayMessage)

        # Synchronize the subscribers using ApproximateTimeSynchronizer
        ts = message_filters.ApproximateTimeSynchronizer([sub_topic1, sub_topic2], queue_size=10, slop=0.1)
        ts.registerCallback(self.callback)

        # Bind the update_plot_size function to the <Configure> event
        # master.bind("<Configure>", self.update_plot_size)

    def callback(self, data1, data2):
        # This method will be called when a new message is received on the /ros_topic
        rospy.loginfo("ROS Topic Data")

        # 这里处理topic内的数据

        # Update scatter plot with new data
        self.update_scatter_plot(Target_Angle, Center_y, Center_x, waypoints_y, waypoints_x)  # Assuming the data is a float, update accordingly

    def update_scatter_plot(self, angle_radians, Center_x, Center_y, waypoints_x, waypoints_y):
        # Update the scatter plot with new data
        self.scatter_plot.clear()
        self.scatter_plot.set_title('Scatter Plot')

        self.scatter_plot.scatter(Center_x, Center_y, color='red', marker='o', label='Center Point')
        
        self.scatter_plot.plot([Center_x, end_x], [Center_y, end_y], color='blue', linestyle='--', label='Line Segment')

        self.scatter_plot.scatter(waypoints_x, waypoints_y, color='green', marker='o', label='Waypoint')

        # 设置x轴和y轴的显示范围
        self.scatter_plot.set_xlim(-100, 100)  # 设置x轴的范围
        self.scatter_plot.set_ylim(-100, 100)  # 设置y轴的范围
        # 设置 x 轴和 y 轴的相同比例尺
        self.scatter_plot.set_aspect('equal')

        # 设置坐标轴标签
        self.scatter_plot.set_xlabel('CARLA Y Axis')
        self.scatter_plot.set_ylabel('CARLA X Axis')

        self.canvas.draw()

    def update_plot_size(self, event):
        # Update the plot size based on the new window size
        new_width = event.width / self.canvas.figure.get_dpi()
        new_height = event.height / self.canvas.figure.get_dpi()
        self.figure.set_size_inches(new_width, new_height)
        self.canvas.draw()


def main():
    root = tk.Tk()
    app = ROS_Tkinter_App(root)
    root.mainloop()


if __name__ == '__main__':
    main()
相关推荐
276695829216 分钟前
tiktok 弹幕 逆向分析
java·python·tiktok·tiktok弹幕·tiktok弹幕逆向分析·a-bogus·x-gnarly
cylat21 分钟前
Day59 经典时序预测模型3
人工智能·python·深度学习·神经网络
嘉恩督26 分钟前
视频人脸处理——人脸面部动作提取
python·音视频
WJ.Polar27 分钟前
Python数据容器-集合set
开发语言·python
smppbzyc1 小时前
2025年亚太杯(中文赛项)数学建模B题【疾病的预测与大数据分析】原创论文讲解(含完整python代码)
python·数学建模·数据分析·数学建模竞赛·亚太杯数学建模·亚太杯
xiaocainiao8811 小时前
Python 实战:构建可扩展的命令行插件引擎
开发语言·python
运器1232 小时前
【一起来学AI大模型】PyTorch DataLoader 实战指南
大数据·人工智能·pytorch·python·深度学习·ai·ai编程
音元系统2 小时前
Copilot 在 VS Code 中的免费替代方案
python·github·copilot
超龄超能程序猿2 小时前
(5)机器学习小白入门 YOLOv:数据需求与图像不足应对策略
人工智能·python·机器学习·numpy·pandas·scipy
cooldream20094 小时前
Python 包管理新时代:深入了解 `uv` 的使用与实践
python·uv·包管理器