參考:ROS2API 及https://index.ros.org/doc/ros2/Concepts/About-Quality-of-Service-Settings
1.概述
ROS2提供了一套非常豐富的服務質量(Quality of Service, QoS)策略用於調整節點之間的通信。眾所周知,在TCP與UDP之間存在着無數的折中設置,QoS既可以設置成像TCP一樣可靠(reliable),也可以設置成像UDP一樣高效(best effort)。不同於ROS1,它主要支持TCP通信,ROS2底層采用的是DDS(Data Distribution Service)傳輸,當DDS工作在損無線網絡(lossy wireless network)中時更有利於best-effect策略,當DDS工作在實時計算系統中時通過設置適合的QoS策略來滿足實時性。
一套QoS策略形成了一個QoS Profile。考慮到為特定的場景選擇正確QoS策略較為復雜,ROS2提供了一套預定義的QoS Profiles,用於常見場景(如傳感器數據)。同時,也提供了特定的Profiles給使用者設置QoS策略。
發布器、訂閱器、服務端和客戶端可以指定Profile,且它們的每個實例都可以單獨指定Profile,但不兼容的Profiles可能導致無法通信。
2.QoS策略
當前,QoS Profile提供了對以下QoS策略的設置:
(1)歷史記錄(History)
保留近期記錄(Keep last):緩存最多N條記錄,可通過隊列長度選項來配置。
保留所有記錄(Keep all):緩存所有記錄,但受限於底層中間件可配置的最大資源。
(2)深度(Depth)
隊列深度(Size of the queue):只能與Keep last配合使用。
(3)可靠性(Reliability)
盡力的(Best effort):嘗試傳輸數據但不保證成功傳輸(當網絡不穩定時可能丟失數據)。
可靠的(Reliable):反復重傳以保證數據成功傳輸。
(4)持續性(Durability)
局部瞬態(Transient local):發布器為晚連接(late-joining)的訂閱器保留數據。
易變態(Volatile):不保留任何數據。
以上每個策略都有系統默認值。這個默認值就是底層中間件的默認值,由DDS供應商工具(如XML配置文件)定義。DDS本身提供了許多可配置的策略。這些策略與ROS1的特征相似,所以在ROS1中是可見的。之后可能會有更多的策略在ROS2中可見。
3.與ROS1的比較
ROS2的History和Depth結合起來類似於ROS1的隊列大小功能。
ROS2的Reliability取Best-effort類似於ROS1的UDPROS(僅roscpp包含此功能),取Reliable類似於ROS1的TCPROS。
ROS2的Durability和隊列深度為1的Depth結合起來類似於ROS1中的latching訂閱器。
4.QoS配置文件
Profile使開發者專注於他們的應用,而無需擔心QoS的各種設置。一個QoS Profile包含一套策略,可以高效地配合特定的用例工作。當前定義了一些默認的Profiles,以下對它們進行介紹。
(1)默認(qos_profiles.h:rmw_qos_profile_system_default)
所有的策略設置為RMW的默認值。不同的RMW默認值可能存在差異。
(2)主題(qos_profiles.h:rmw_qos_profile_default)
為了保證ROS1和ROS2之間的過渡,有必要設計一套相似的網絡行為。於是,設置發布器和訂閱器的默認Profile為(Keep last, 10, Reliable, Volatile)。
(3)服務(qos_profiles.h:rmw_qos_profile_services_default)
與發布器和訂閱者器一樣,服務首先得reliable。其次,Volatile對服務也是必須的,否則會收到過時的請求。盡管客戶端已被設計避免接收多次響應,但服務端沒有設計如何處理過時的請求產生的副作用。服務Profile的詳細取值為(Keep last, 10, Reliable, Volatile)。
(4)參數(qos_profiles.h:rmw_qos_profile_parameters)
參數是基於服務的,所以有相似的Profile。不同之處參數具有更大的隊列深度,以避免丟失請求(例如當在參數客戶端不能訪問參數服務端時)。參數Profile的詳細取值為(Keep last, 1000, Reliable, Volatile)。
(5)參數事件(qos_profiles.h:rmw_qos_profile_parameter_events)
與參數Profile相同。
(6)傳感器數據(qos_profiles.h:rmw_qos_profile_sensor_data)
在大多數用例中,需要實時讀取傳感器的數據而無需讀取所有數據。也就是說,開發者希望盡快地獲取最新數據,為此可以丟失一些數據。因此,傳感器需要Best effort和更小的隊列深度,其Profile詳細取值為(Keep last, 5, Best effort, Volatile)。
以上Profiles更多信息可參見~\ros2\include\rmw\qos_profiles.h。這些Profiles的取值會根據社區的反饋意見進一步的調整
雖然ROS2提供了一些常用的QoS Profiles,但DDS中定義的策略允許ROS用戶基於現有的DDS文檔提供的大量的信息來為其特定的用例設置QoS Profile。
5.QoS兼容性
注意:以下內容以發布器和訂閱器舉例闡述,但同樣適合於服務端和客戶端。
發布器和訂閱器可以分別指定自己的OoS Profiles。只有當它們的Profiles兼容時,兩者才能建立連接。Profile的兼容性基於"請求與提供"(Request vs Offerer)模型,只有當訂閱器的策略沒有發布器的嚴格時,連接才能建立,且建立的連接使用嚴格度低的策略。
ROS2中存在兼容性問題的OoS策略是Durability和Reliability。下面的展示了不同策略配置的兼容性結果:
Durability的兼容性配置:
Publisher |
Subscriber |
Connection |
Result |
Volatile |
Volatile |
Yes |
Volatile |
Volatile |
Transient local |
No |
|
Transient local |
Volatile |
Yes |
Volatile |
Transient local |
Transient local |
Yes |
Transient local |
Reliability的兼容性配置:
Publisher |
Subscriber |
Connection |
Result |
Best effort |
Best effort |
Yes |
Best effort |
Best effort |
Reliable |
No |
|
Reliable |
Best effort |
Yes |
Best effort |
Reliable |
Reliable |
Yes |
Reliable |
為建立連接,所有影響兼容性的策略都必須設置成可以兼容的。換句話說,假設如發布器和訂閱器的Reliability是兼容的,但Durability不兼容,那么也不能建立連接,反之亦然。
QoS學習日志