Skip to content

Commit 149e501

Browse files
authored
Add demo of how to use qos overrides (#474)
Signed-off-by: Ivan Santiago Paunovic <[email protected]>
1 parent e62dde8 commit 149e501

File tree

6 files changed

+268
-1
lines changed

6 files changed

+268
-1
lines changed

quality_of_service_demo/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,19 @@ Example output:
178178
```
179179

180180
For information about how to tune QoS settings for large messages see [DDS tuning](https://index.ros.org/doc/ros2/Troubleshooting/DDS-tuning/).
181+
182+
## Qos overrides
183+
184+
You can use QoS overrides parameters for making QoS profiles configurable when starting a node.
185+
Create a parameters yaml file, similar to the examples in the `params_file` folder, and run:
186+
187+
```
188+
# you can use `$(ros2 pkg prefix quality_of_service_demo_cpp)/share/quality_of_service_demo_cpp/params_file/example_qos_overrides.yaml` instead of `/path/to/yaml/file` to use the example installed yaml file.
189+
ros2 run quality_of_service_demo_cpp qos_overrides_talker --ros-args --params-file /path/to/yaml/file
190+
```
191+
192+
in another terminal:
193+
194+
```
195+
ros2 run quality_of_service_demo_cpp qos_overrides_listener --ros-args --params-file /path/to/yaml/file
196+
```

quality_of_service_demo/rclcpp/CMakeLists.txt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,34 @@ rclcpp_components_register_node(message_lost
6060
PLUGIN "quality_of_service_demo::MessageLostTalker"
6161
EXECUTABLE message_lost_talker)
6262

63+
add_library(qos_overrides SHARED
64+
src/qos_overrides_listener.cpp
65+
src/qos_overrides_talker.cpp
66+
)
67+
ament_target_dependencies(qos_overrides
68+
"rclcpp"
69+
"rclcpp_components"
70+
"rcutils"
71+
"sensor_msgs"
72+
)
73+
target_compile_definitions(qos_overrides
74+
PRIVATE "QUALITY_OF_SERVICE_DEMO_BUILDING_DLL")
75+
rclcpp_components_register_node(qos_overrides
76+
PLUGIN "quality_of_service_demo::QosOverridesListener"
77+
EXECUTABLE qos_overrides_listener)
78+
rclcpp_components_register_node(qos_overrides
79+
PLUGIN "quality_of_service_demo::QosOverridesTalker"
80+
EXECUTABLE qos_overrides_talker)
81+
6382
install(TARGETS
64-
message_lost
83+
message_lost qos_overrides
6584
ARCHIVE DESTINATION lib
6685
LIBRARY DESTINATION lib
6786
RUNTIME DESTINATION bin
6887
)
6988

89+
install(DIRECTORY params_file DESTINATION ${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME})
90+
7091
if(BUILD_TESTING)
7192
find_package(ament_lint_auto REQUIRED)
7293
ament_lint_auto_find_test_dependencies()
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
qos_overrides_talker: # node name
2+
ros__parameters: # All parameters are nested in this key
3+
qos_overrides: # Parameter group for all qos overrides
4+
/qos_overrides_chatter: # Parameter group for the topic
5+
publisher: # Profile for publishers in the topic
6+
# publisher_my_id: # Profile for publishers in the topic with id="my_id"
7+
reliability: reliable
8+
depth: 9
9+
# depth: 11 # Uncomment this line to make the validation callback fail
10+
qos_overrides_listener:
11+
ros__parameters:
12+
qos_overrides:
13+
/qos_overrides_chatter:
14+
subscription: # Profile for subscriptions in the topic
15+
# subscription_my_id: # Profile for subscriptions in the topic with id="my_id"
16+
reliability: reliable
17+
depth: 9
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**:
2+
ros__parameters:
3+
qos_overrides:
4+
/qos_overrides_chatter:
5+
publisher:
6+
reliability: reliable
7+
depth: 9
8+
subscription:
9+
reliability: reliable
10+
depth: 9
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright 2020 Open Source Robotics Foundation, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "rclcpp/qos_overriding_options.hpp"
16+
#include "rclcpp/rclcpp.hpp"
17+
#include "rclcpp_components/register_node_macro.hpp"
18+
19+
#include "sensor_msgs/msg/image.hpp"
20+
21+
#include "quality_of_service_demo/visibility_control.h"
22+
23+
namespace quality_of_service_demo
24+
{
25+
class QosOverridesListener : public rclcpp::Node
26+
{
27+
public:
28+
QUALITY_OF_SERVICE_DEMO_PUBLIC
29+
explicit QosOverridesListener(const rclcpp::NodeOptions & options)
30+
: Node("qos_overrides_listener", options)
31+
{
32+
// Callback that will be used when a message is received.
33+
auto callback =
34+
[this](const sensor_msgs::msg::Image::SharedPtr msg) -> void
35+
{
36+
rclcpp::Time now = this->get_clock()->now();
37+
auto diff = now - msg->header.stamp;
38+
RCLCPP_INFO(
39+
this->get_logger(),
40+
"I heard an image. Message single trip latency: [%f]",
41+
diff.seconds());
42+
};
43+
rclcpp::SubscriptionOptions sub_opts;
44+
// Update the subscription options to allow reconfigurable qos settings.
45+
sub_opts.qos_overriding_options = rclcpp::QosOverridingOptions {
46+
{
47+
// Here all policies that are desired to be reconfigurable are listed.
48+
rclcpp::QosPolicyKind::Depth,
49+
rclcpp::QosPolicyKind::Durability,
50+
rclcpp::QosPolicyKind::History,
51+
rclcpp::QosPolicyKind::Reliability,
52+
},
53+
[](const rclcpp::QoS & qos) {
54+
/** This is a qos validation callback, that can optionally be provided.
55+
* Here, arbitrary constraints in the final qos profile can be checked.
56+
* The function will return true if the user provided qos profile is accepted.
57+
* If the profile is not accepted, the user will get an InvalidQosOverridesException.
58+
*/
59+
rclcpp::QosCallbackResult result;
60+
result.successful = false;
61+
if (qos.depth() > 10u) {
62+
result.reason = "expected history depth less or equal than 10";
63+
return result;
64+
}
65+
result.successful = true;
66+
return result;
67+
}
68+
/**
69+
* The "id" option is useful when you want to have subscriptions
70+
* listening to the same topic with different QoS profiles within a node.
71+
* You can try uncommenting and modifying
72+
* `qos_overrides./qos_overrides_topic.subscription`
73+
* to
74+
* `qos_overrides./qos_overrides_topic.subscription_custom_identifier`
75+
*
76+
* Uncomment the next line to try it.
77+
*/
78+
// , "custom_identifier"
79+
};
80+
// create the subscription
81+
sub_ = create_subscription<sensor_msgs::msg::Image>(
82+
"qos_overrides_chatter", 1, callback, sub_opts);
83+
}
84+
85+
private:
86+
rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr sub_;
87+
};
88+
89+
} // namespace quality_of_service_demo
90+
91+
RCLCPP_COMPONENTS_REGISTER_NODE(quality_of_service_demo::QosOverridesListener)
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Copyright 2020 Open Source Robotics Foundation, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <chrono>
16+
#include <memory>
17+
#include <string>
18+
#include <utility>
19+
#include <vector>
20+
21+
#include "rcutils/cmdline_parser.h"
22+
23+
#include "rclcpp/rclcpp.hpp"
24+
#include "rclcpp_components/register_node_macro.hpp"
25+
26+
#include "sensor_msgs/msg/image.hpp"
27+
28+
#include "quality_of_service_demo/visibility_control.h"
29+
30+
using namespace std::chrono_literals;
31+
32+
namespace quality_of_service_demo
33+
{
34+
35+
class QosOverridesTalker : public rclcpp::Node
36+
{
37+
public:
38+
QUALITY_OF_SERVICE_DEMO_PUBLIC
39+
explicit QosOverridesTalker(const rclcpp::NodeOptions & options)
40+
: Node("qos_overrides_talker", options)
41+
{
42+
// Timer callback
43+
auto publish_message =
44+
[this]() -> void
45+
{
46+
for (size_t i = 0; i < 1u * 1024u * 1024u; ++i) {
47+
msg_.data.push_back(0);
48+
}
49+
rclcpp::Time now = this->get_clock()->now();
50+
msg_.header.stamp = now;
51+
RCLCPP_INFO(
52+
this->get_logger(),
53+
"Publishing an image, sent at [%f]",
54+
now.seconds());
55+
56+
pub_->publish(msg_);
57+
};
58+
59+
rclcpp::PublisherOptions pub_opts;
60+
// Update the subscription options to allow reconfigurable qos settings.
61+
pub_opts.qos_overriding_options = rclcpp::QosOverridingOptions {
62+
{
63+
// Here all policies that are desired to be reconfigurable are listed.
64+
rclcpp::QosPolicyKind::Depth,
65+
rclcpp::QosPolicyKind::Durability,
66+
rclcpp::QosPolicyKind::History,
67+
rclcpp::QosPolicyKind::Reliability
68+
},
69+
[](const rclcpp::QoS & qos) {
70+
/** This is a qos validation callback, that can optionally be provided.
71+
* Here, arbitrary constraints in the final qos profile can be checked.
72+
* The function will return true if the user provided qos profile is accepted.
73+
* If the profile is not accepted, the user will get an InvalidQosOverridesException.
74+
*/
75+
rclcpp::QosCallbackResult result;
76+
result.successful = false;
77+
if (qos.depth() > 10u) {
78+
result.reason = "expected history depth less or equal than 10";
79+
return result;
80+
}
81+
result.successful = true;
82+
return result;
83+
}
84+
/**
85+
* The "id" option is useful when you want to have subscriptions
86+
* listening to the same topic with different QoS profiles within a node.
87+
* You can try uncommenting and modifying
88+
* `qos_overrides./qos_overrides_topic.subscription`
89+
* to
90+
* `qos_overrides./qos_overrides_topic.subscription_custom_identifier`
91+
*
92+
* Uncomment the next line to try it.
93+
*/
94+
// , "custom_identifier"
95+
};
96+
97+
// Create a publisher
98+
pub_ = this->create_publisher<sensor_msgs::msg::Image>("qos_overrides_chatter", 1, pub_opts);
99+
100+
// Use a timer to schedule periodic message publishing.
101+
timer_ = this->create_wall_timer(3s, publish_message);
102+
}
103+
104+
private:
105+
sensor_msgs::msg::Image msg_;
106+
rclcpp::Publisher<sensor_msgs::msg::Image>::SharedPtr pub_;
107+
rclcpp::TimerBase::SharedPtr timer_;
108+
};
109+
110+
} // namespace quality_of_service_demo
111+
112+
RCLCPP_COMPONENTS_REGISTER_NODE(quality_of_service_demo::QosOverridesTalker)

0 commit comments

Comments
 (0)