Опции политики Качества сервиса (QoS) допускают изменение поведения коммуникации в сети ROS 2. Политики QoS изменяются для определенных коммуникационных объектов, таких как издатели и подписчики, и изменяют способ, которым сообщения обработаны в объекте и транспортированы между ними. Для любых сообщений, чтобы передать между двумя коммуникационными объектами, их политики QoS должны быть совместимыми.
Доступное Качество Обслуживаний в ROS 2:
History
- Режим очереди сообщений
Depth
- Размер очереди сообщений
Reliability
- Гарантия доставки сообщений
Durability
- Персистентность сообщений
Для получения дополнительной информации займитесь Качеством Сервисных Настроек.
История и глубина, политики QoS определяют поведение коммуникационных объектов, когда сообщения делаются доступными быстрее, чем, они могут быть обработаны. Это - в основном, беспокойство о подписчиках, которые получают сообщения, все еще обрабатывая предыдущее сообщение. Сообщения помещаются в очередь обработки, которая может влиять на издателей также. История имеет опции:
"keeplast"
- У очереди обработки сообщения есть максимальный размер, равный Depth
значение. Если очередь полна, самые старые сообщения пропущены, чтобы создать место для более новых единиц.
"keepall"
- Очередь обработки сообщения пытается сохранить все сообщения полученными в очереди, пока не обработано.
При любой установке истории размер очереди подвергается пределам аппаратного ресурса. Если подписчик вызывает коллбэк, когда новые сообщения получены, размер очереди также ограничивается максимальным пределом рекурсии.
В ситуациях, где важно обработать все сообщения, increating Depth
значение или использование History,"keepall"
рекомендуется.
В этом примере показано, как установить издателя и подписчика для отправки и получения сообщений облака точек. Издатель Depth
20, и subsriber история установлена в "keepall"
. Подписчик использует вызов назад, чтобы построить метку времени для каждого сообщения, чтобы показать синхронизацию обработки каждого сообщения. Первоначальные сообщения занимают больше времени к процессу, но все сообщения в конечном счете обрабатываются от очереди.
% Create a publisher to provide sensor data robotNode = ros2node("/simple_robot"); lidarPub = ros2publisher(robotNode,"/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,"/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,"/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(3) % 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"
подписчик, потому что сообщения, как гарантируют, не будут переданы. В противоположном situatiuon, "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