diff --git a/README.md b/README.md
index ed05d23..2ab7dc4 100644
--- a/README.md
+++ b/README.md
@@ -78,6 +78,7 @@ Parameters are provided to configure the behavior of the bridge. These parameter
* __use_compression__: Use websocket compression (permessage-deflate). Suited for connections with smaller bandwith, at the cost of additional CPU load.
* (ROS 1) __max_update_ms__: The maximum number of milliseconds to wait in between polling `roscore` for new topics, services, or parameters. Defaults to `5000`.
* (ROS 2) __num_threads__: The number of threads to use for the ROS node executor. This controls the number of subscriptions that can be processed in parallel. 0 means one thread per CPU core. Defaults to `0`.
+ * (ROS 2) __min_qos_depth__: Minimum depth used for the QoS profile of subscriptions. Defaults to `1`. This is to set a lower limit for a subscriber's QoS depth which is computed by summing up depths of all publishers. See also [#208](https://github.com/foxglove/ros-foxglove-bridge/issues/208).
* (ROS 2) __max_qos_depth__: Maximum depth used for the QoS profile of subscriptions. Defaults to `10`.
* (ROS 2) __capabilities__: List of supported [server capabilities](https://github.com/foxglove/ws-protocol/blob/main/docs/spec.md). Defaults to `[clientPublish,parameters,parametersSubscribe,services,connectionGraph]`.
diff --git a/ros2_foxglove_bridge/include/foxglove_bridge/param_utils.hpp b/ros2_foxglove_bridge/include/foxglove_bridge/param_utils.hpp
index 5b455a2..805639a 100644
--- a/ros2_foxglove_bridge/include/foxglove_bridge/param_utils.hpp
+++ b/ros2_foxglove_bridge/include/foxglove_bridge/param_utils.hpp
@@ -14,6 +14,7 @@ constexpr char PARAM_SEND_BUFFER_LIMIT[] = "send_buffer_limit";
constexpr char PARAM_USETLS[] = "tls";
constexpr char PARAM_CERTFILE[] = "certfile";
constexpr char PARAM_KEYFILE[] = "keyfile";
+constexpr char PARAM_MIN_QOS_DEPTH[] = "min_qos_depth";
constexpr char PARAM_MAX_QOS_DEPTH[] = "max_qos_depth";
constexpr char PARAM_TOPIC_WHITELIST[] = "topic_whitelist";
constexpr char PARAM_SERVICE_WHITELIST[] = "service_whitelist";
@@ -25,6 +26,7 @@ constexpr char PARAM_CLIENT_TOPIC_WHITELIST[] = "client_topic_whitelist";
constexpr int64_t DEFAULT_PORT = 8765;
constexpr char DEFAULT_ADDRESS[] = "0.0.0.0";
constexpr int64_t DEFAULT_SEND_BUFFER_LIMIT = 10000000;
+constexpr int64_t DEFAULT_MIN_QOS_DEPTH = 1;
constexpr int64_t DEFAULT_MAX_QOS_DEPTH = 10;
void declareParameters(rclcpp::Node* node);
diff --git a/ros2_foxglove_bridge/launch/foxglove_bridge_launch.xml b/ros2_foxglove_bridge/launch/foxglove_bridge_launch.xml
index 4aee6b3..5524bb0 100644
--- a/ros2_foxglove_bridge/launch/foxglove_bridge_launch.xml
+++ b/ros2_foxglove_bridge/launch/foxglove_bridge_launch.xml
@@ -8,6 +8,7 @@
+
@@ -24,6 +25,7 @@
+
diff --git a/ros2_foxglove_bridge/src/param_utils.cpp b/ros2_foxglove_bridge/src/param_utils.cpp
index db4d5ef..becf88c 100644
--- a/ros2_foxglove_bridge/src/param_utils.cpp
+++ b/ros2_foxglove_bridge/src/param_utils.cpp
@@ -60,6 +60,18 @@ void declareParameters(rclcpp::Node* node) {
keyfileDescription.read_only = true;
node->declare_parameter(PARAM_KEYFILE, "", keyfileDescription);
+ auto minQosDepthDescription = rcl_interfaces::msg::ParameterDescriptor{};
+ minQosDepthDescription.name = PARAM_MIN_QOS_DEPTH;
+ minQosDepthDescription.type = rcl_interfaces::msg::ParameterType::PARAMETER_INTEGER;
+ minQosDepthDescription.description = "Minimum depth used for the QoS profile of subscriptions.";
+ minQosDepthDescription.read_only = true;
+ minQosDepthDescription.additional_constraints = "Must be a non-negative integer";
+ minQosDepthDescription.integer_range.resize(1);
+ minQosDepthDescription.integer_range[0].from_value = 0;
+ minQosDepthDescription.integer_range[0].to_value = INT32_MAX;
+ minQosDepthDescription.integer_range[0].step = 1;
+ node->declare_parameter(PARAM_MIN_QOS_DEPTH, DEFAULT_MIN_QOS_DEPTH, minQosDepthDescription);
+
auto maxQosDepthDescription = rcl_interfaces::msg::ParameterDescriptor{};
maxQosDepthDescription.name = PARAM_MAX_QOS_DEPTH;
maxQosDepthDescription.type = rcl_interfaces::msg::ParameterType::PARAMETER_INTEGER;
diff --git a/ros2_foxglove_bridge/src/ros2_foxglove_bridge.cpp b/ros2_foxglove_bridge/src/ros2_foxglove_bridge.cpp
index e86e18e..5df0b81 100644
--- a/ros2_foxglove_bridge/src/ros2_foxglove_bridge.cpp
+++ b/ros2_foxglove_bridge/src/ros2_foxglove_bridge.cpp
@@ -52,6 +52,7 @@ class FoxgloveBridge : public rclcpp::Node {
const auto useTLS = this->get_parameter(PARAM_USETLS).as_bool();
const auto certfile = this->get_parameter(PARAM_CERTFILE).as_string();
const auto keyfile = this->get_parameter(PARAM_KEYFILE).as_string();
+ _minQosDepth = static_cast(this->get_parameter(PARAM_MIN_QOS_DEPTH).as_int());
_maxQosDepth = static_cast(this->get_parameter(PARAM_MAX_QOS_DEPTH).as_int());
const auto topicWhiteList = this->get_parameter(PARAM_TOPIC_WHITELIST).as_string_array();
_topicWhitelistPatterns = parseRegexStrings(this, topicWhiteList);
@@ -441,6 +442,7 @@ class FoxgloveBridge : public rclcpp::Node {
std::mutex _clientAdvertisementsMutex;
std::mutex _servicesMutex;
std::unique_ptr _rosgraphPollThread;
+ size_t _minQosDepth = DEFAULT_MIN_QOS_DEPTH;
size_t _maxQosDepth = DEFAULT_MAX_QOS_DEPTH;
std::shared_ptr> _clockSubscription;
bool _useSimTime = false;
@@ -556,7 +558,7 @@ class FoxgloveBridge : public rclcpp::Node {
depth = std::min(_maxQosDepth, depth + qos.depth());
}
- rclcpp::QoS qos{rclcpp::KeepLast(std::max(depth, 1lu))};
+ rclcpp::QoS qos{rclcpp::KeepLast(std::max(depth, _minQosDepth))};
// If all endpoints are reliable, ask for reliable
if (reliabilityReliableEndpointsCount == publisherInfo.size()) {