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

如何编写ROS2发布节点,从YAML文件定时发布消息运行Autoware节点?

问题描述

我尝试运行Autoware生态中的单个ROS2节点,已通过ros2 bag record记录所有输入话题,得到若干包含消息内容的YAML文件(代码片段如下)。由于无法使用ros2 bag play进行仿真,我需要编写一个发布节点,从YAML文件中读取消息并每隔X秒发布一次,请问是否可行?

YAML消息片段:

header:
  stamp:
    sec: 1585897255
    nanosec: 366032919
  frame_id: map
child_frame_id: base_link
pose:
  pose:
    position:
      x: 89530.4904175517
      y: 42411.98934126079
      z: -3.608327379954426
    orientation:
      x: 0.003322876298139578
      y: -0.014172646821833243
      z: 0.8596727738629668
      w: 0.5106376567135674
  covariance:
  - 0.004823699025978851
  - 0.0014223050349292865
  - 0.0
  - 0.0
  - 0.0
  - -0.00033930002493972645
  - 0.0014223050349292876
  - 0.003066485845419473
  - 0.0
  - 0.0
  - 0.0
  - -0.00018709073063899757
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - -0.0003393000249397263
  - -0.00018709073063899755
  - 0.0
  - 0.0
  - 0.0
  - 6.080293039040077e-05
twist:
  twist:
    linear:
      x: 13.072203929530296
      y: 0.0
      z: 0.0
    angular:
      x: 0.0
      y: 0.0
      z: -0.008810670840086786
  covariance:
  - 0.03935738353508679
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - -5.688005653640222e-11
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - -5.688005653640594e-11
  - 0.0
  - 0.0
  - 0.0
  - 0.0
  - 0.0015608784670052972
解答

完全可行,以下是实现思路和示例代码:

核心步骤

  • 确定消息类型:从YAML结构判断,这是nav_msgs/msg/Odometry类型的消息,需确认目标节点订阅的话题类型与之匹配。
  • 读取YAML文件:使用YAML解析库(如Python的pyyaml)加载文件内容。
  • 构造ROS2消息:将YAML中的字段逐一映射到ROS2消息的对应属性上。
  • 定时发布:借助ROS2的定时器,每隔X秒发布一次构造好的消息。

Python示例代码

import rclpy
from rclpy.node import Node
from nav_msgs.msg import Odometry
import yaml
from rclpy.time import Time

class YamlPublisher(Node):
    def __init__(self):
        super().__init__('yaml_odom_publisher')
        # 创建发布者,话题名和消息类型根据实际情况修改
        self.publisher_ = self.create_publisher(Odometry, '/odom', 10)
        # 加载YAML文件,替换为你的文件路径
        with open('/path/to/your/odom_msg.yaml', 'r') as f:
            self.yaml_data = yaml.safe_load(f)
        # 设置发布间隔,单位秒,替换为你需要的X值
        timer_period = 1.0
        self.timer = self.create_timer(timer_period, self.timer_callback)

    def timer_callback(self):
        msg = Odometry()
        # 填充header
        msg.header.stamp = Time(seconds=self.yaml_data['header']['stamp']['sec'], nanoseconds=self.yaml_data['header']['stamp']['nanosec']).to_msg()
        msg.header.frame_id = self.yaml_data['header']['frame_id']
        msg.child_frame_id = self.yaml_data['child_frame_id']
        # 填充pose
        msg.pose.pose.position.x = self.yaml_data['pose']['pose']['position']['x']
        msg.pose.pose.position.y = self.yaml_data['pose']['pose']['position']['y']
        msg.pose.pose.position.z = self.yaml_data['pose']['pose']['position']['z']
        msg.pose.pose.orientation.x = self.yaml_data['pose']['pose']['orientation']['x']
        msg.pose.pose.orientation.y = self.yaml_data['pose']['pose']['orientation']['y']
        msg.pose.pose.orientation.z = self.yaml_data['pose']['pose']['orientation']['z']
        msg.pose.pose.orientation.w = self.yaml_data['pose']['pose']['orientation']['w']
        msg.pose.covariance = self.yaml_data['pose']['covariance']
        # 填充twist
        msg.twist.twist.linear.x = self.yaml_data['twist']['twist']['linear']['x']
        msg.twist.twist.linear.y = self.yaml_data['twist']['twist']['linear']['y']
        msg.twist.twist.linear.z = self.yaml_data['twist']['twist']['linear']['z']
        msg.twist.twist.angular.x = self.yaml_data['twist']['twist']['angular']['x']
        msg.twist.twist.angular.y = self.yaml_data['twist']['twist']['angular']['y']
        msg.twist.twist.angular.z = self.yaml_data['twist']['twist']['angular']['z']
        msg.twist.covariance = self.yaml_data['twist']['covariance']
        # 发布消息
        self.publisher_.publish(msg)
        self.get_logger().info('发布Odometry消息')

def main(args=None):
    rclpy.init(args=args)
    yaml_publisher = YamlPublisher()
    rclpy.spin(yaml_publisher)
    yaml_publisher.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

注意事项

  • 确保安装依赖:执行pip install pyyaml,同时正确配置ROS2环境。
  • 若有多个YAML文件对应不同话题,需为每个话题单独编写发布逻辑,或在一个节点中创建多个发布者。
  • 根据实际需求修改话题名、消息类型和YAML文件路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:51:01