ROS2 使用方式与典型场景
四、使用方式与典型场景
示例一:带 QoS 的 Python 发布订阅
import rclpy
from rclpy.node import Node
from rclpy.qos import QoSProfile, ReliabilityPolicy, HistoryPolicy, DurabilityPolicy
from sensor_msgs.msg import LaserScan
class ScanRelay(Node):
def __init__(self):
super().__init__("scan_relay")
sensor_qos = QoSProfile(
reliability=ReliabilityPolicy.BEST_EFFORT,
durability=DurabilityPolicy.VOLATILE,
history=HistoryPolicy.KEEP_LAST,
depth=5,
)
self.sub = self.create_subscription(
LaserScan, "/scan", self.on_scan, sensor_qos)
self.pub = self.create_publisher(LaserScan, "/scan_filtered", sensor_qos)
def on_scan(self, msg):
msg.ranges = [r if r == r else float("inf") for r in msg.ranges]
self.pub.publish(msg)
def main():
rclpy.init()
node = ScanRelay()
try:
rclpy.spin(node)
finally:
node.destroy_node()
rclpy.shutdown()
if __name__ == "__main__":
main()
这里 r != r 用来滤掉 NaN(值为 NaN 时它不等于自身),把无效点换成无穷远,是雷达数据预处理的常见写法。
示例二:Python launch 文件与参数
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
def generate_launch_description():
use_sim_time = LaunchConfiguration("use_sim_time")
return LaunchDescription([
DeclareLaunchArgument("use_sim_time", default_value="false"),
Node(
package="my_robot",
executable="scan_relay",
name="scan_relay",
parameters=[{"use_sim_time": use_sim_time},
{"max_range": 12.0}],
remappings=[("/scan", "/lidar/scan")],
output="screen",
),
])
运行:ros2 launch my_robot bringup.launch.py use_sim_time:=true。参数用 := 传,比改 YAML 更适合临时调试。
示例三:参数 YAML
scan_relay:
ros__parameters:
use_sim_time: true
max_range: 12.0
min_range: 0.15
frame_id: laser
加载方式是在 launch 里用 parameters=["config/params.yaml"],顶层键必须与节点的 name 完全一致,写错了参数不会报错,只会静默用默认值。
示例四:录包与回放
ros2 bag record -o run1 /scan /odom /tf /tf_static /cmd_vel
ros2 bag info run1
ros2 bag play run1 --clock --rate 0.5
--clock 会发布仿真时间,回放时配合 use_sim_time:=true 才能让算法按数据里的时间戳运行。如果录包时丢了高频传感器数据,多半是订阅端 QoS 不匹配,可以用 QoS 覆盖文件把录制端的策略改成 best_effort。
适合与不适合
- 适合:多传感器融合、模块化开发、需要导航/机械臂/仿真等成熟生态、需要跨语言协作。
- 不适合:资源极小的单片机(用 micro-ROS)、需要亚毫秒级确定性的硬实时控制回路(要配合实时内核与执行器配置,且通信层仍有抖动)、模块固定且对延迟极致敏感的小系统(自研通信可能更简单)。

