ROS2---std_msgs基础消息包

std_msgs 是ROS 2(Robot Operating System 2)里的基础消息包,它定义了一系列简单却常用的消息类型,为不同节点间的通信提供了基础的数据格式。

1. 消息包概述

std_msgs 包包含了多种基础消息类型,这些类型用于表示常见的数据,如布尔值、整数、浮点数、字符串、时间等。在ROS 2系统里,不同节点通过发布和订阅这些消息类型来交换数据。

2. 常见消息类型

2.1 布尔类型(Bool

用于表示布尔值,即 true 或者 false

plaintext 复制代码
bool data
  • 用途:常用于开关控制、状态指示等场景。例如,控制机器人的某个功能开启或关闭,或者表示传感器是否检测到特定目标。
  • 示例代码(Python)
python 复制代码
import rclpy
from rclpy.node import Node
from std_msgs.msg import Bool

class BoolPublisher(Node):
    def __init__(self):
        super().__init__('bool_publisher')
        self.publisher_ = self.create_publisher(Bool, 'bool_topic', 10)
        timer_period = 1  # seconds
        self.timer = self.create_timer(timer_period, self.timer_callback)
        self.i = 0

    def timer_callback(self):
        msg = Bool()
        msg.data = self.i % 2 == 0
        self.publisher_.publish(msg)
        self.get_logger().info('Publishing: "%s"' % msg.data)
        self.i += 1


def main(args=None):
    rclpy.init(args=args)
    bool_publisher = BoolPublisher()
    rclpy.spin(bool_publisher)
    bool_publisher.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()
2.2 整数类型
  • 有符号整数Int8Int16Int32Int64 分别表示8位、16位、32位和64位有符号整数。以 Int32 为例:
plaintext 复制代码
int32 data
  • 无符号整数UInt8UInt16UInt32UInt64 分别表示8位、16位、32位和64位无符号整数。以 UInt32 为例:
plaintext 复制代码
uint32 data
  • 用途:可用于计数、索引、状态编码等场景。比如,统计传感器采集的数据数量,或者表示设备的状态编码。
2.3 浮点类型
  • Float32Float64 :分别表示32位和64位浮点数。以 Float32 为例:
plaintext 复制代码
float32 data
  • 用途:常用于表示连续的物理量,像温度、速度、角度等。
2.4 字符串类型(String

用于表示文本信息。

plaintext 复制代码
string data
  • 用途:可传递文本指令、日志信息、描述性信息等。例如,发送控制指令或者记录系统的运行日志。
  • 示例代码(Python)
python 复制代码
import rclpy
from rclpy.node import Node
from std_msgs.msg import String

class StringPublisher(Node):
    def __init__(self):
        super().__init__('string_publisher')
        self.publisher_ = self.create_publisher(String, 'string_topic', 10)
        timer_period = 1  # seconds
        self.timer = self.create_timer(timer_period, self.timer_callback)
        self.i = 0

    def timer_callback(self):
        msg = String()
        msg.data = 'Hello World: %d' % self.i
        self.publisher_.publish(msg)
        self.get_logger().info('Publishing: "%s"' % msg.data)
        self.i += 1


def main(args=None):
    rclpy.init(args=args)
    string_publisher = StringPublisher()
    rclpy.spin(string_publisher)
    string_publisher.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()
2.5 时间和持续时间类型
  • Time:表示时间点,由秒和纳秒构成。
plaintext 复制代码
uint32 sec
uint32 nanosec
  • Duration:表示时间间隔,同样由秒和纳秒构成。
plaintext 复制代码
int32 sec
uint32 nanosec
  • 用途:在需要进行时间同步、时间戳记录或者计算时间间隔的场景中使用。例如,记录传感器数据的采集时间,或者计算两个事件之间的时间差。
2.6 头消息类型(Header

为其他消息提供元数据,包含序列号、时间戳和坐标系ID。

plaintext 复制代码
uint32 seq
builtin_interfaces/Time stamp
string frame_id
  • seq:消息序列号,用于标识消息的顺序。
  • stamp:时间戳,记录消息的发布时间。
  • frame_id:坐标系ID,指示消息数据所在的坐标系。
  • 用途:在多传感器融合、坐标变换等场景中,确保数据的时间一致性和空间一致性。
2.7 空消息类型(Empty

不包含任何数据。

plaintext 复制代码
  • 用途:通常用于触发某个动作或者事件,而不需要传递具体的数据。例如,触发一个系统的重置操作。

3. 消息使用的注意事项

3.1 数据类型匹配

在发布和订阅消息时,要保证消息类型一致,不然会引发运行时错误。

3.2 时间戳处理

对于包含时间戳的消息(如 HeaderTime),要正确设置和处理时间戳,以保证数据的时间一致性。

3.3 坐标系管理

使用 Header 中的 frame_id 时,要确保坐标系的定义和使用是正确的,避免坐标变换出错。

4. 消息的编译和使用流程

4.1 消息定义

.msg 文件里定义消息类型,例如 Bool.msg

plaintext 复制代码
bool data
4.2 消息编译

package.xml 中添加依赖:

xml 复制代码
<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>

CMakeLists.txt 中配置消息编译:

cmake 复制代码
find_package(ament_cmake REQUIRED)
find_package(rosidl_default_generators REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/Bool.msg"
  DEPENDENCIES builtin_interfaces
)

ament_export_dependencies(rosidl_default_runtime)

ament_package()

然后运行 colcon build 进行编译。

4.3 在代码中使用

在发布和订阅节点里引入相应的消息类型并使用。

5. 高级应用

5.1 消息嵌套

可以把 std_msgs 中的消息类型嵌套到自定义消息里,构建更复杂的消息结构。

5.2 消息序列化和反序列化

ROS 2会自动处理消息的序列化和反序列化,不过在某些特殊场景下,可能需要手动处理。


鉴于ROS2架构的项目中std_msgs/Header有至关重要的作用,所以下面对其进行详细介绍

在ROS 2(Robot Operating System 2)中,std_msgs/Header 消息类型同样扮演着至关重要的角色,它为其他消息提供了元数据信息,对于消息的时间同步、坐标系管理以及消息追踪等功能起着关键作用。

1. 消息定义与结构

std_msgs/Header 消息类型定义如下:

plaintext 复制代码
# 消息序列号
uint32 seq
# 时间戳
builtin_interfaces/Time stamp
# 坐标系ID
string frame_id

2. 各字段详细解释

2.1 序列号(seq
  • 数据类型uint32,即无符号32位整数。
  • 作用 :该字段用于唯一标识消息的发布顺序。每次发布消息时,序列号会依次递增。它的主要用途是帮助接收方判断消息是否有丢失或乱序情况。例如,在实时性要求较高的机器人控制系统中,接收节点可以通过检查 seq 的连续性来确保消息的完整性。
  • 使用场景 :在处理大量消息流时,通过 seq 可以快速定位和识别消息的顺序,有助于调试和错误排查。
2.2 时间戳(stamp
  • 数据类型builtin_interfaces/Time,它包含 sec(秒)和 nanosec(纳秒)两个子字段,用于精确表示时间点。
  • 作用:记录消息发布的时间,在多传感器数据融合、运动规划和控制等场景中,时间戳是实现数据同步和时序分析的关键信息。例如,在融合激光雷达和摄像头数据时,需要根据时间戳将不同传感器的数据进行对齐。
  • 使用场景
    • 数据同步:确保不同传感器或节点产生的数据在时间上的一致性。
    • 历史数据分析:通过时间戳可以对消息进行排序和筛选,便于后续的分析和处理。
    • 故障诊断:在排查问题时,时间戳可以帮助确定事件发生的先后顺序,辅助定位问题。
2.3 坐标系ID(frame_id
  • 数据类型string,即字符串类型。
  • 作用 :指定消息中数据所参考的坐标系。在机器人的运动控制和环境感知中,不同的传感器和执行器可能使用不同的坐标系,通过 frame_id 可以明确数据的空间参考,方便进行坐标变换和数据融合。例如,激光雷达数据可能是在 base_link(机器人基座坐标系)下采集的,而地图数据可能是在 map(全局地图坐标系)下定义的,通过 frame_id 可以将它们统一到同一坐标系下进行处理。
  • 使用场景
    • 坐标变换 :结合ROS 2的TF(Transform)库,根据 frame_id 进行不同坐标系之间的转换。
    • 可视化 :在RViz等可视化工具中,根据 frame_id 正确显示数据的位置和姿态。
    • 多机器人协作 :在多机器人系统中,不同机器人可能使用不同的坐标系,frame_id 有助于区分和协调各机器人的数据。

3. 代码示例

以下是一个使用Python和ROS 2的示例,展示如何创建和使用 Header 消息:

python 复制代码
import rclpy
from rclpy.node import Node
from std_msgs.msg import Header
from builtin_interfaces.msg import Time
import time

class HeaderPublisher(Node):
    def __init__(self):
        super().__init__('header_publisher')
        self.publisher_ = self.create_publisher(Header, 'header_topic', 10)
        timer_period = 1  # seconds
        self.timer = self.create_timer(timer_period, self.timer_callback)
        self.seq = 0

    def timer_callback(self):
        header = Header()
        header.seq = self.seq
        current_time = self.get_clock().now().to_msg()
        header.stamp = current_time
        header.frame_id = 'base_link'

        self.publisher_.publish(header)
        self.get_logger().info(f'Publishing Header: seq={header.seq}, stamp={header.stamp}, frame_id={header.frame_id}')
        self.seq += 1

def main(args=None):
    rclpy.init(args=args)
    header_publisher = HeaderPublisher()
    rclpy.spin(header_publisher)
    header_publisher.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

4. 使用注意事项

4.1 时间戳设置

在实际应用中,要确保 stamp 字段的时间准确,建议使用ROS 2提供的时钟接口(如 get_clock().now())来获取当前时间,避免手动设置可能导致的时间不一致问题。

4.2 坐标系命名规范

frame_id 应遵循ROS 2的命名约定,通常使用小写字母、数字和下划线,避免使用特殊字符。常见的坐标系名称包括 base_link(机器人基座坐标系)、map(全局地图坐标系)等。

4.3 序列号管理

seq 字段由发布节点负责维护和递增,接收节点可以通过比较序列号来检测消息丢失或乱序情况。

5. 应用场景

5.1 多传感器融合

在机器人同时配备激光雷达、摄像头、IMU等多种传感器的情况下,不同传感器采集的数据可能具有不同的时间戳和坐标系。通过 Header 消息,可以将这些数据在时间和空间上进行统一,从而实现更准确的环境感知和决策。

5.2 运动规划与控制

在机器人的运动规划和控制过程中,需要实时获取机器人的位置、姿态等信息。Header 消息中的时间戳和坐标系ID可以帮助控制系统准确地跟踪机器人的状态,确保运动的精确性和稳定性。

5.3 日志记录与调试

在开发和调试过程中,Header 消息可以作为重要的日志信息,记录消息的发布顺序、时间和坐标系等关键信息,有助于快速定位和解决问题。

综上所述,std_msgs/Header 消息类型在ROS 2中是一个基础且重要的组成部分,它为消息传递提供了必要的元数据,对于实现机器人系统的高效运行和数据处理起着不可或缺的作用。


倏忽温风至,因循小暑来。

竹喧先觉雨,山暗已闻雷。 ---元稹

相关推荐
双叶83614 分钟前
(51单片机)点阵屏LED显示图片(点阵屏LED教程)(74Hc595教程)
c语言·开发语言·单片机·嵌入式硬件·51单片机
Python私教25 分钟前
Java手写链表全攻略:从单链表到双向链表的底层实现艺术
java·python·链表
Stara051125 分钟前
YOLO11改进——融合BAM注意力机制增强图像分类与目标检测能力
人工智能·python·深度学习·目标检测·计算机视觉·yolov11
xiongmaodaxia_z71 小时前
python每日一练
开发语言·python·算法
Chandler241 小时前
Go:接口
开发语言·后端·golang
Jasmin Tin Wei1 小时前
css易混淆的知识点
开发语言·javascript·ecmascript
&白帝&1 小时前
java HttpServletRequest 和 HttpServletResponse
java·开发语言
ErizJ1 小时前
Golang|Channel 相关用法理解
开发语言·后端·golang
automan021 小时前
golang 在windows 系统的交叉编译
开发语言·后端·golang
LitchiCheng1 小时前
MuJoCo 机械臂关节路径规划+轨迹优化+末端轨迹可视化(附代码)
人工智能·深度学习·机器人