< >
Home » ROS2与Matlab入门教程 » ROS2与Matlab入门教程-在ROS2中管理Quality of Service Policies

ROS2与Matlab入门教程-在ROS2中管理Quality of Service Policies

说明:

  • 介绍如何在在ROS2中管理Quality of Service Policies

介绍:

  • Quality of Service (QoS)Policies允许更改 ROS 2 网络内的通信行为

  • 针对特定通信对象(例如发布者和订阅者)修改 QoS 策略,并更改对象中处理消息和在它们之间传输消息的方式

  • 对于在两个通信对象之间传递的任何消息,它们的 QoS 策略必须兼容。

  • ROS 2 中可用的 Quality of Service Policies:History- 消息尾模式,Depth- 消息队列大小,Reliability- 消息的传递保证,Durability- 消息的持久性

步骤:

  • 历史和深度QoS 策略决定了当消息可用的速度快于它们的处理速度时通信对象的行为。这主要是订阅者在处理前一条消息的同时接收消息的问题。消息被放入处理队列中,这也会影响发布者。历史有以下选择:

    • "keeplast"- 消息处理队列的最大大小等于该Depth值。如果队列已满,则最旧的消息将被丢弃,以便为新消息腾出空间

    • "keepall"- 消息处理队列尝试保留队列中收到的所有消息,直到处理完毕

  • 在任一历史设置下,队列大小受硬件资源限制。如果订阅者在收到新消息时调用回调,则队列大小也受到最大递归限制的限制

  • 在处理所有消息很重要的情况下,建议增加Depth值或使用History,"keepall"

  • 此示例说明如何设置发布者和订阅者以发送和接收点云消息。发布Depth者为 20,订阅者历史设置为"keepall"。订阅者使用回调来绘制每条消息的时间戳,以显示处理每条消息的时间。初始消息需要更长的时间来处理,但所有消息最终都会从队列中处理

% Create a publisher to provide sensor data
robotNode = ros2node("/simple_robot");
lidarPub = ros2publisher(robotNode,"/laser_scan","sensor_msgs/PointCloud2",...
    "History","keeplast","Depth",20);

% Create a subscriber representing localization, requiring all scan data
hFig = figure;
hAxesLidar = axes("Parent",hFig);
title("Message Timeline (Keep All)")
localizationSub = ros2subscriber(robotNode,"/laser_scan",...
    @(msg)exampleHelperROS2PlotTimestamps(msg,hAxesLidar),...
    "History","keepall");

% Send messages, simulating an extremely fast sensor
load robotPoseLidarData.mat lidarScans
for iMsg = 1:numel(lidarScans)
    send(lidarPub,lidarScans(iMsg))
end

% Allow messages to arrive, then remove the localization subscriber
pause(3)

请输入图片描述

clear localizationSub
  • 在被丢弃的消息不太重要并且只有最新信息真正重要的情况下,建议使用较小的队列来提高性能并确保使用最新信息。

  • 此示例显示了对第一条消息的更快处理,并且仍然可以获取所有消息。但是,根据您的资源,您可能会看到消息被丢弃

% Create a subscriber representing user interface display
hFig = figure;
hAxesLidar2 = axes("Parent",hFig);
title("Message Timeline (Keep Last 1)")
scanDisplaySub = ros2subscriber(robotNode,"/laser_scan",...
    @(msg)exampleHelperROS2PlotTimestamps(msg,hAxesLidar2),...
    "History","keeplast","Depth",1);
for iMsg = 1:numel(lidarScans)
    send(lidarPub,lidarScans(iMsg))
end

% Allow messages to arrive, then remove the subscriber and publisher
pause(3)

请输入图片描述

clear lidarPub scanDisplaySub
  • 可靠性,可靠性QoS 策略确定是否保证消息的传递,并具有以下选项:

    • "reliable"- 发布者不断向订阅者发送消息,直到订阅者确认收到消息

    • "besteffort"- 发布者只发送一次消息,不确认订阅者收到

  • 当"reliable"必须处理所有数据并且任何丢弃的消息都可能影响结果时,连接很有用。此示例发布Odometry消息并使用订阅者回调来绘制位置。因为对于"reliable"设置,所有位置都绘制在图中

% Create a publisher for odometry data
odomPub = ros2publisher(robotNode,"/odom","nav_msgs/Odometry",...
    "Reliability","reliable");

% Create a subscriber for localization
hFig = figure;
hAxesReliable = axes("Parent",hFig);
title("Robot Position (Reliable Connection)")
xlabel("X (m)")
ylabel("Y (m)")
odomPlotSub = ros2subscriber(robotNode,"/odom",...
    @(msg)exampleHelperROS2PlotOdom(msg,hAxesReliable,"ok"),...
    "Reliability","reliable");

% Send messages, simulating an extremely fast sensor
load robotPoseLidarData.mat odomData
for iMsg = 1:numel(odomData)
    send(odomPub,odomData(iMsg))
end

pause(5)    % Allow messages to arrive and be plotted

请输入图片描述

% Temporarily prevent reliable subscriber from reacting to new messages
odomPlotSub.NewMessageFcn = [];
  • 如果"besteffort"丢弃的消息是可接受的,则连接有助于避免影响性能。如果发布者设置为"reliable",订阅者设置为"besteffort",则发布者将该连接视为仅需要"besteffort",并且不确认传递。与同一主题的订阅者的连接"reliable"保证来自同一发布者。

  • 此示例使用"besteffort"订阅者,但由于对网络的影响较小,仍会接收所有消息。

hFig = figure;
hAxesBestEffort = axes("Parent",hFig);
title("Message Timeline (Best Effort Connection)")
odomTimingSub = ros2subscriber(robotNode,"/odom",...
   @(msg)exampleHelperROS2PlotTimestamps(msg,hAxesBestEffort),...
    "Reliability","besteffort");
for iMsg = 1:numel(odomData)
    send(odomPub,odomData(iMsg))
end

pause(3)    % Allow messages to arrive and be plotted

请输入图片描述

  • 兼容性

  • 在设置可靠性时,确保兼容性是一个重要的考虑因素。具有"reliable"选项集的订阅者需要符合该标准的发布者。任何"besteffort"发布者都不会连接到"reliable"订阅者,因为不能保证传递消息

  • 在相反的情况下,"reliable"发布者和"besteffort"订阅者确实连接了,但是"besteffort"在接收消息时连接的行为就像没有确认一样。此示例显示发布者向已设置"besteffort"的订阅者发送消息。"besteffort"同样,由于对网络的影响较小,"besteffort"连接足以处理所有消息

% Reactivate reliable subscriber to show no messages received
odomPlotSub.NewMessageFcn = @(msg)exampleHelperROS2PlotOdom(msg,hAxesReliable,"*r");

% Send messages from a best-effort publisher
bestEffortOdomPub = ros2publisher(robotNode,"/odom","nav_msgs/Odometry",...
    "Reliability","besteffort");
for iMsg = 1:numel(odomData)
    send(bestEffortOdomPub,odomData(iMsg))
end

% Allow messages to arrive, then remove odometry publishers and subscribers
pause(3)    % Allow messages to arrive and be plotted

请输入图片描述

clear odomPub bestEffortOdomPub odomPlotSub odomTimingSub
  • 耐用性和深度

  • 持久性QoS 策略控制后期加入连接的消息的持久性,并具有以下选项:

    • "transientlocal"- 对于发布者,维护已发送的消息。如果订阅者"transientlocal"之后加入具有持久性的网络,则发布者将持久消息发送给订阅者。

    • "volatile"- 发布者在发送消息后不会持久化消息,订阅者不会向发布者请求持久化消息。

  • 具有持久性的发布者持久化的消息数量"transientlocal"也由Depth输入控制。

  • 订阅者仅根据他们的个人Depth设置请求最近消息的数量。发布者仍然可以为其他订阅者存储更多消息以获取更多消息。例如,机器人位置的完整列表可能有助于可视化其路径,但定位算法可能只对最后一个已知位置感兴趣。

  • 此示例说明了通过使用本地化订阅者来显示当前位置和使用绘图订阅者来显示队列中的所有位置

% Publish robot location information
posePub = ros2publisher(robotNode,"/bot_position","geometry_msgs/Pose2D",...
    "Durability","transientlocal","Depth",100);
load robotPoseLidarData.mat robotPositions
for iMsg = 1:numel(robotPositions)
    send(posePub,robotPositions(iMsg))
    pause(0.2)     % Allow for processing time
end

% Create a localization update subscriber that only needs current position
localUpdateSub = ros2subscriber(robotNode,"/bot_position",@disp,...
    "Durability","transientlocal","Depth",1);
pause(1)    % Allow message to arrive



    x: 0.1047
    y: -2.3168
theta: -8.5194


% Create a visualization subscriber to show where the robot has been
hFig = figure;
hAxesMoreMsgs = axes("Parent",hFig);
title("Robot Position (Transient Local Connection)")
xlabel("X (m)")
ylabel("Y (m)")
hold on
posePlotSub = ros2subscriber(robotNode,"/bot_position",...
    @(msg)plot(hAxesMoreMsgs,msg.x,msg.y,"ok"),...
    "Durability","transientlocal","Depth",20);
pause(3)    % Allow messages to arrive and be plotted

请输入图片描述

  • 兼容性。与可靠性类似,不兼容的持久性设置会阻止发布者和订阅者之间的通信。

  • 具有持久性的订阅者"transientlocal"需要具有持久性的发布者"transientlocal"。如果发布者是"volatile",则不会与"transientlocal"订阅者建立连接。

  • 如果发布者是"transientlocal"和订阅者"volatile“,则创建该连接,而不向订阅者发送持久消息。

% Reset plotting behavior
posePlotSub.NewMessageFcn = @(msg)plot(hAxesMoreMsgs,msg.x,msg.y,"xr");

% Send messages from volatile publisher
volatilePosePub = ros2publisher(robotNode,"/bot_position",...
    "Durability","volatile");
for iMsg = 1:numel(robotPositions)
    send(volatilePosePub,robotPositions(iMsg))
    pause(0.2)     % Allow for processing time
end
  • "transientlocal"任何一个订阅者都没有收到任何消息
% Remove pose publishers and subscribers
clear posePub volatilePosePub localUpdateSub posePlotSub robotNode

纠错,疑问,交流: 请进入讨论区点击加入Q群

获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号


标签: ros2与matlab入门教程