Опции политики качества обслуживания (QoS) позволяют изменять поведение связи в сети ROS 2. Политики QoS изменяются для определенных объектов связи, таких как издатели и подписчики, и изменяют способ обработки сообщений в объекте и перемещения между ними. Чтобы любые сообщения передавались между двумя объектами связи, их политики QoS должны быть совместимыми.
Доступные политики качества обслуживания в ROS 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)
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"
- Издатель отправляет сообщение только один раз и не подтверждает, что подписчик получает его.
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
% 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
Обеспечение совместимости является важным фактором при настройке надежности. Абонент с "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