exponenta event banner

Управление политиками качества обслуживания в ROS 2

Параметры политики качества обслуживания (QoS) позволяют изменять поведение связи в сети ROS 2. Политики QoS изменяются для определенных объектов связи, таких как издатели и подписчики, и меняют способ обработки сообщений в объекте и передачи между ними. Для передачи любых сообщений между двумя объектами связи их политики QoS должны быть совместимы.

Доступные политики качества обслуживания в АФК 2:

  • 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)

Figure contains an axes. The axes with title Message Timeline (Keep All) contains 40 objects of type line, text.

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)

Figure contains an axes. The axes with title Message Timeline (Keep Last 1) contains 40 objects of type line, text.

clear lidarPub scanDisplaySub

Надежность

Политика обеспечения качества обслуживания определяет, следует ли гарантировать доставку сообщений, и имеет следующие опции:

  • "reliable" - Издатель непрерывно отправляет сообщение абоненту до тех пор, пока абонент не подтвердит получение сообщения.

  • "besteffort" - Издатель отправляет сообщение только один раз и не подтверждает его получение подписчиком.

Надежный

A "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

Figure contains an axes. The axes with title Robot Position (Reliable Connection) contains 40 objects of type line, text.

% Temporarily prevent reliable subscriber from reacting to new messages
odomPlotSub.NewMessageFcn = [];

Наилучшие усилия

A "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

Figure contains an axes. The axes with title Message Timeline (Best Effort Connection) contains 40 objects of type line, text.

Совместимость

Обеспечение совместимости является важным фактором при определении надежности. Абонент с "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

Figure contains an axes. The axes with title Message Timeline (Best Effort Connection) contains 80 objects of type line, text.

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

Figure contains an axes. The axes with title Robot Position (Transient Local Connection) contains 20 objects of type line.

Совместимость

Аналогично надежности, несовместимые настройки долговечности могут препятствовать общению между издателями и подписчиками. Абонент с "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