警告
您正在閱讀已達到生命週期結束(end-of-life,EOL)版本的 ROS 2 文件,該版本不再正式受支援。如果您想獲取最新資訊,請參見 Lyrical。
DDS 調校資訊
本頁面提供一些參數調校的指引,這些調校是針對在實際情況中於 Linux 上使用各種 DDS 實作時所遇到的問題。我們在 Linux 上或使用某個供應商時發現的問題,也可能發生在其他未在此記錄的平台和供應商上。
以下建議是調校的起點;它們在特定系統和環境中有效,但調校可能因多種因素而異。在除錯時,您可能需要根據訊息大小、網路拓撲等因素來增加或減少數值。
重要的是要認識到,調校參數可能會消耗資源,並可能影響系統中超出預期改進範圍的部分。對於每個案例,應權衡提升可靠性的好處與其帶來的任何不利影響。
跨供應商調校
問題: 透過有損(通常是 WiFi)連線傳送資料時,若某些 IP 片段被丟棄,可能會導致接收端的內核緩衝區被填滿。
當一個 UDP 封包缺少至少一個 IP 片段時,其餘已接收的片段會填滿內核緩衝區。預設情況下,Linux 內核在嘗試重組封包片段 30 秒後會逾時。由於此時內核緩衝區已滿(預設大小為 256KB),無法再接收新的片段,因此連線會看似「掛起」很長一段時間。
此問題在所有 DDS 供應商中普遍存在,因此解決方案涉及調整內核參數。
解決方案: 使用盡力而為(best-effort)的 QoS 設定,而非可靠(reliable)模式。
Best-effort settings reduce the amount of sent data since it will not resend incomplete samples and therefore will flood the network less than reliable. If the kernel buffer for IP fragments gets full, though, the symptom is still the same (blocking for 30s). This solution should improve the issue somewhat without having to adjust parameters.
解決方案: 降低 ipfrag_time 參數的值。
``net.ipv4.ipfrag_time / /proc/sys/net/ipv4/ipfrag_time``(預設 30 秒):在記憶體中保留 IP 片段的時間(秒)。
透過執行以下指令將值降低,例如降至 3 秒:
sudo sysctl net.ipv4.ipfrag_time=3
Reducing this parameter’s value also reduces the window of time where no fragments are received. The parameter is global for all incoming fragments, so the feasibility of reducing its value needs to be considered for every environment.
解決方案: 提高 ipfrag_high_thresh 參數的值。
``net.ipv4.ipfrag_high_thresh / /proc/sys/net/ipv4/ipfrag_high_thresh``(預設:262144 位元組):用於重組 IP 片段的最大記憶體。
透過執行以下指令提高值,例如提高到 128MB:
sudo sysctl net.ipv4.ipfrag_high_thresh=134217728 # (128 MB)
Significantly increasing this parameter’s value is an attempt to ensure that the buffer never becomes completely full.
However, the value would likely have to be significantly high to hold all data received during the time window of ipfrag_time, assuming every UDP packet lacks one fragment.
Fast RTPS 調校
問題: Fast RTPS 在透過 WiFi 運作時,會以大量資料或快速發布的資料淹沒網路。
請參閱 跨供應商調校 下的解決方案。
Cyclone DDS 調校
問題: Cyclone DDS 即使使用可靠設定並透過有線網路傳輸,仍無法可靠地傳遞大型訊息。
This issue should be addressed soon. Until then, we’ve come up with the following solution (debugged using this test program):
解決方案: 增加 Linux 內核的最大接收緩衝區大小和 Cyclone 使用的最小 socket 接收緩衝區大小。
解決 9MB 訊息的調整:
透過執行以下指令設定最大接收緩衝區大小 rmem_max:
sudo sysctl -w net.core.rmem_max=2147483647
或者透過編輯 /etc/sysctl.d/10-cyclone-max.conf 檔案將其永久設定為包含以下內容:
net.core.rmem_max=2147483647
接下來,若要設定 Cyclone 請求的最小 socket 接收緩衝區大小,請編寫一個供 Cyclone 在啟動時使用的組態檔,如下所示:
<?xml version="1.0" encoding="UTF-8" ?>
<CycloneDDS xmlns="https://cdds.io/config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://cdds.io/config
https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/master/etc/cyclonedds.xsd">
<Domain id="any">
<Internal>
<MinimumSocketReceiveBufferSize>10MB</MinimumSocketReceiveBufferSize>
</Internal>
</Domain>
</CycloneDDS>
然後,每當您要執行節點時,請設定以下環境變數:
CYCLONEDDS_URI=file:///absolute/path/to/config_file.xml
RTI Connext 調校
問題: Connext 即使使用可靠設定並透過有線網路傳輸,仍無法可靠地傳遞大型訊息。
解決方案: 使用此 Connext QoS 設定檔,並提高 rmem_max 參數。
透過執行以下指令設定最大接收緩衝區大小 rmem_max:
sudo sysctl -w net.core.rmem_max=4194304
透過將 Linux 內核中的 net.core.rmem_max 調校至 4MB,QoS 設定檔可實現真正可靠的行為。
此組態已證明可透過 SHMEM|UDPv4 以及在單台機器上僅使用 UDPv4 可靠地傳遞訊息。也在多機器組態下進行了測試,rmem_max 設為 4MB 和 20MB(兩台機器透過 1Gbps 乙太網路連接),結果沒有訊息丟失,平均訊息傳遞時間分別為 700 毫秒和 371 毫秒。
Without configuring the kernel’s rmem_max, the same Connext QoS profile took up to 12 seconds for the data to be delivered.
However, it always at least managed to complete the delivery.
解決方案: 使用 Connext QoS 設定檔,*無需*調整 rmem_max。
The ROS2TEST_QOS_PROFILES.xml file was configured using RTI’s documentation on configuring flow controllers. It has slow, medium and fast flow controllers (seen in the Connext QoS profile link).
中速流量控制器在我們的情況下產生了最佳結果。然而,控制器仍需要根據其運行的特定機器/網路/環境進行調校。Connext 流量控制器可用於調整頻寬及其發送資料的積極程度,但一旦超過特定設定的頻寬,效能就會開始下降。