ROS 2 rclcpp + rcl - lyrical  lyrical
ROS 2 C++ Client Library with ROS Client Library
qos.cpp
1 // Copyright 2019 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.hpp"
16 
17 #include <string>
18 
19 #include "rclcpp/logging.hpp"
20 
21 #include "rmw/error_handling.h"
22 #include "rmw/types.h"
23 #include "rmw/qos_profiles.h"
24 
25 namespace rclcpp
26 {
27 
28 std::string qos_policy_name_from_kind(rmw_qos_policy_kind_t policy_kind)
29 {
30  switch (policy_kind) {
31  case RMW_QOS_POLICY_DURABILITY:
32  return "DURABILITY_QOS_POLICY";
33  case RMW_QOS_POLICY_DEADLINE:
34  return "DEADLINE_QOS_POLICY";
35  case RMW_QOS_POLICY_LIVELINESS:
36  return "LIVELINESS_QOS_POLICY";
37  case RMW_QOS_POLICY_RELIABILITY:
38  return "RELIABILITY_QOS_POLICY";
39  case RMW_QOS_POLICY_HISTORY:
40  return "HISTORY_QOS_POLICY";
41  case RMW_QOS_POLICY_LIFESPAN:
42  return "LIFESPAN_QOS_POLICY";
43  case RMW_QOS_POLICY_DEPTH:
44  return "DEPTH_QOS_POLICY";
45  case RMW_QOS_POLICY_LIVELINESS_LEASE_DURATION:
46  return "LIVELINESS_LEASE_DURATION_QOS_POLICY";
47  case RMW_QOS_POLICY_AVOID_ROS_NAMESPACE_CONVENTIONS:
48  return "AVOID_ROS_NAMESPACE_CONVENTIONS_QOS_POLICY";
49  default:
50  return "INVALID_QOS_POLICY";
51  }
52 }
53 
55  rmw_qos_history_policy_t history_policy_arg, size_t depth_arg,
56  bool print_depth_warning)
57 : history_policy(history_policy_arg), depth(depth_arg)
58 {
59  if (history_policy == RMW_QOS_POLICY_HISTORY_KEEP_LAST && depth == 0 && print_depth_warning) {
60  RCLCPP_WARN_ONCE(
62  "rclcpp"),
63  "A zero depth with KEEP_LAST doesn't make sense; no data could be stored. "
64  "This will be interpreted as SYSTEM_DEFAULT");
65  }
66 }
67 
69 QoSInitialization::from_rmw(const rmw_qos_profile_t & rmw_qos)
70 {
71  switch (rmw_qos.history) {
72  case RMW_QOS_POLICY_HISTORY_KEEP_ALL:
73  return KeepAll();
74  case RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT:
75  return KeepLast(rmw_qos.depth, false);
76  case RMW_QOS_POLICY_HISTORY_KEEP_LAST:
77  case RMW_QOS_POLICY_HISTORY_UNKNOWN:
78  return KeepLast(rmw_qos.depth);
79  default:
80  throw std::invalid_argument(
81  "Invalid history policy enum value passed to QoSInitialization::from_rmw");
82  }
83 }
84 
85 KeepAll::KeepAll()
86 : QoSInitialization(RMW_QOS_POLICY_HISTORY_KEEP_ALL, 0)
87 {}
88 
89 KeepLast::KeepLast(size_t depth, bool print_depth_warning)
90 : QoSInitialization(RMW_QOS_POLICY_HISTORY_KEEP_LAST, depth, print_depth_warning)
91 {
92 }
93 
95  const QoSInitialization & qos_initialization,
96  const rmw_qos_profile_t & initial_profile)
97 : rmw_qos_profile_(initial_profile)
98 {
99  rmw_qos_profile_.history = qos_initialization.history_policy;
100  rmw_qos_profile_.depth = qos_initialization.depth;
101 }
102 
103 QoS::QoS(size_t history_depth)
104 : QoS(KeepLast(history_depth))
105 {}
106 
107 rmw_qos_profile_t &
109 {
110  return rmw_qos_profile_;
111 }
112 
113 const rmw_qos_profile_t &
115 {
116  return rmw_qos_profile_;
117 }
118 
119 QoS &
120 QoS::history(rmw_qos_history_policy_t history)
121 {
122  rmw_qos_profile_.history = history;
123  return *this;
124 }
125 
126 QoS &
127 QoS::history(HistoryPolicy history)
128 {
129  rmw_qos_profile_.history = static_cast<rmw_qos_history_policy_t>(history);
130  return *this;
131 }
132 
133 QoS &
134 QoS::keep_last(size_t depth)
135 {
136  if (depth == 0) {
137  RCLCPP_WARN_ONCE(
139  "rclcpp"),
140  "A zero depth with KEEP_LAST doesn't make sense; no data could be stored."
141  "This will be interpreted as SYSTEM_DEFAULT");
142  }
143 
144  rmw_qos_profile_.history = RMW_QOS_POLICY_HISTORY_KEEP_LAST;
145  rmw_qos_profile_.depth = depth;
146  return *this;
147 }
148 
149 QoS &
151 {
152  rmw_qos_profile_.history = RMW_QOS_POLICY_HISTORY_KEEP_ALL;
153  rmw_qos_profile_.depth = 0;
154  return *this;
155 }
156 
157 QoS &
158 QoS::reliability(rmw_qos_reliability_policy_t reliability)
159 {
160  rmw_qos_profile_.reliability = reliability;
161  return *this;
162 }
163 
164 QoS &
165 QoS::reliability(ReliabilityPolicy reliability)
166 {
167  rmw_qos_profile_.reliability = static_cast<rmw_qos_reliability_policy_t>(reliability);
168  return *this;
169 }
170 
171 QoS &
173 {
174  return this->reliability(RMW_QOS_POLICY_RELIABILITY_RELIABLE);
175 }
176 
177 QoS &
179 {
180  return this->reliability(RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT);
181 }
182 
183 QoS &
185 {
186  return this->reliability(RMW_QOS_POLICY_RELIABILITY_BEST_AVAILABLE);
187 }
188 
189 QoS &
190 QoS::durability(rmw_qos_durability_policy_t durability)
191 {
192  rmw_qos_profile_.durability = durability;
193  return *this;
194 }
195 
196 QoS &
197 QoS::durability(DurabilityPolicy durability)
198 {
199  rmw_qos_profile_.durability = static_cast<rmw_qos_durability_policy_t>(durability);
200  return *this;
201 }
202 
203 QoS &
205 {
206  return this->durability(RMW_QOS_POLICY_DURABILITY_VOLATILE);
207 }
208 
209 QoS &
211 {
212  return this->durability(RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL);
213 }
214 
215 QoS &
217 {
218  return this->durability(RMW_QOS_POLICY_DURABILITY_BEST_AVAILABLE);
219 }
220 
221 QoS &
222 QoS::deadline(rmw_time_t deadline)
223 {
224  rmw_qos_profile_.deadline = deadline;
225  return *this;
226 }
227 
228 QoS &
230 {
231  return this->deadline(deadline.to_rmw_time());
232 }
233 
234 QoS &
235 QoS::lifespan(rmw_time_t lifespan)
236 {
237  rmw_qos_profile_.lifespan = lifespan;
238  return *this;
239 }
240 
241 QoS &
243 {
244  return this->lifespan(lifespan.to_rmw_time());
245 }
246 
247 QoS &
248 QoS::liveliness(rmw_qos_liveliness_policy_t liveliness)
249 {
250  rmw_qos_profile_.liveliness = liveliness;
251  return *this;
252 }
253 
254 QoS &
255 QoS::liveliness(LivelinessPolicy liveliness)
256 {
257  rmw_qos_profile_.liveliness = static_cast<rmw_qos_liveliness_policy_t>(liveliness);
258  return *this;
259 }
260 
261 
262 QoS &
263 QoS::liveliness_lease_duration(rmw_time_t liveliness_lease_duration)
264 {
265  rmw_qos_profile_.liveliness_lease_duration = liveliness_lease_duration;
266  return *this;
267 }
268 
269 QoS &
270 QoS::liveliness_lease_duration(const rclcpp::Duration & liveliness_lease_duration)
271 {
272  return this->liveliness_lease_duration(liveliness_lease_duration.to_rmw_time());
273 }
274 
275 QoS &
276 QoS::avoid_ros_namespace_conventions(bool avoid_ros_namespace_conventions)
277 {
278  rmw_qos_profile_.avoid_ros_namespace_conventions = avoid_ros_namespace_conventions;
279  return *this;
280 }
281 
282 HistoryPolicy
284 {
285  return static_cast<HistoryPolicy>(rmw_qos_profile_.history);
286 }
287 
288 size_t
289 QoS::depth() const {return rmw_qos_profile_.depth;}
290 
291 ReliabilityPolicy
293 {
294  return static_cast<ReliabilityPolicy>(rmw_qos_profile_.reliability);
295 }
296 
297 DurabilityPolicy
299 {
300  return static_cast<DurabilityPolicy>(rmw_qos_profile_.durability);
301 }
302 
303 Duration
304 QoS::deadline() const {return Duration::from_rmw_time(rmw_qos_profile_.deadline);}
305 
306 Duration
307 QoS::lifespan() const {return Duration::from_rmw_time(rmw_qos_profile_.lifespan);}
308 
309 LivelinessPolicy
311 {
312  return static_cast<LivelinessPolicy>(rmw_qos_profile_.liveliness);
313 }
314 
315 Duration
317 {
318  return Duration::from_rmw_time(rmw_qos_profile_.liveliness_lease_duration);
319 }
320 
321 bool
323 {
324  return rmw_qos_profile_.avoid_ros_namespace_conventions;
325 }
326 
327 namespace
328 {
330 bool operator==(const rmw_time_t & left, const rmw_time_t & right)
331 {
332  return left.sec == right.sec && left.nsec == right.nsec;
333 }
334 } // unnamed namespace
335 
336 bool operator==(const QoS & left, const QoS & right)
337 {
338  const auto & pl = left.get_rmw_qos_profile();
339  const auto & pr = right.get_rmw_qos_profile();
340  return pl.history == pr.history &&
341  pl.depth == pr.depth &&
342  pl.reliability == pr.reliability &&
343  pl.durability == pr.durability &&
344  pl.deadline == pr.deadline &&
345  pl.lifespan == pr.lifespan &&
346  pl.liveliness == pr.liveliness &&
347  pl.liveliness_lease_duration == pr.liveliness_lease_duration &&
348  pl.avoid_ros_namespace_conventions == pr.avoid_ros_namespace_conventions;
349 }
350 
351 bool operator!=(const QoS & left, const QoS & right)
352 {
353  return !(left == right);
354 }
355 
356 QoSCheckCompatibleResult
357 qos_check_compatible(const QoS & publisher_qos, const QoS & subscription_qos)
358 {
359  rmw_qos_compatibility_type_t compatible;
360  const size_t reason_size = 2048u;
361  char reason_c_str[reason_size] = "";
362  rmw_ret_t ret = rmw_qos_profile_check_compatible(
363  publisher_qos.get_rmw_qos_profile(),
364  subscription_qos.get_rmw_qos_profile(),
365  &compatible,
366  reason_c_str,
367  reason_size);
368  if (RMW_RET_OK != ret) {
369  std::string error_str(rmw_get_error_string().str);
370  rmw_reset_error();
372  }
373 
375  result.reason = std::string(reason_c_str);
376 
377  switch (compatible) {
378  case RMW_QOS_COMPATIBILITY_OK:
379  result.compatibility = QoSCompatibility::Ok;
380  break;
381  case RMW_QOS_COMPATIBILITY_WARNING:
382  result.compatibility = QoSCompatibility::Warning;
383  break;
384  case RMW_QOS_COMPATIBILITY_ERROR:
385  result.compatibility = QoSCompatibility::Error;
386  break;
387  default:
389  "Unexpected compatibility value returned by rmw '" + std::to_string(compatible) +
390  "'"};
391  }
392  return result;
393 }
394 
395 ClockQoS::ClockQoS(const QoSInitialization & qos_initialization)
396 // Using `rmw_qos_profile_sensor_data` intentionally.
397 // It's best effort and `qos_initialization` is overriding the depth to 1.
398 : QoS(qos_initialization, rmw_qos_profile_sensor_data)
399 {}
400 
401 SensorDataQoS::SensorDataQoS(const QoSInitialization & qos_initialization)
402 : QoS(qos_initialization, rmw_qos_profile_sensor_data)
403 {}
404 
405 ParametersQoS::ParametersQoS(const QoSInitialization & qos_initialization)
406 : QoS(qos_initialization, rmw_qos_profile_parameters)
407 {}
408 
409 ServicesQoS::ServicesQoS(const QoSInitialization & qos_initialization)
410 : QoS(qos_initialization, rmw_qos_profile_services_default)
411 {}
412 
413 ParameterEventsQoS::ParameterEventsQoS(const QoSInitialization & qos_initialization)
414 : QoS(qos_initialization, rmw_qos_profile_parameter_events)
415 {}
416 
417 RosoutQoS::RosoutQoS(const QoSInitialization & rosout_initialization)
418 : QoS(rosout_initialization, rmw_qos_profile_rosout_default)
419 {}
420 
421 SystemDefaultsQoS::SystemDefaultsQoS(const QoSInitialization & qos_initialization)
422 : QoS(qos_initialization, rmw_qos_profile_system_default)
423 {}
424 
425 BestAvailableQoS::BestAvailableQoS(const QoSInitialization & qos_initialization)
426 : QoS(qos_initialization, rmw_qos_profile_best_available)
427 {}
428 
429 } // namespace rclcpp
rmw_time_t to_rmw_time() const
Convert Duration into rmw_time_t.
Definition: duration.cpp:267
Encapsulation of Quality of Service settings.
Definition: qos.hpp:116
QoS & durability_best_available()
Set the durability setting to best available.
Definition: qos.cpp:216
QoS & best_effort()
Set the reliability setting to best effort.
Definition: qos.cpp:178
bool avoid_ros_namespace_conventions() const
Get the avoid ros namespace convention setting.
Definition: qos.cpp:322
QoS & reliable()
Set the reliability setting to reliable.
Definition: qos.cpp:172
QoS & keep_all()
Set the history to keep all.
Definition: qos.cpp:150
rclcpp::Duration deadline() const
Get the deadline duration setting.
Definition: qos.cpp:304
DurabilityPolicy durability() const
Get the durability policy.
Definition: qos.cpp:298
rclcpp::Duration lifespan() const
Get the lifespan duration setting.
Definition: qos.cpp:307
QoS & durability_volatile()
Set the durability setting to volatile.
Definition: qos.cpp:204
ReliabilityPolicy reliability() const
Get the reliability policy.
Definition: qos.cpp:292
LivelinessPolicy liveliness() const
Get the liveliness policy.
Definition: qos.cpp:310
HistoryPolicy history() const
Get the history qos policy.
Definition: qos.cpp:283
QoS(const QoSInitialization &qos_initialization, const rmw_qos_profile_t &initial_profile=rmw_qos_profile_default)
Create a QoS by specifying only the history policy and history depth.
Definition: qos.cpp:94
QoS & reliability_best_available()
Set the reliability setting to best available.
Definition: qos.cpp:184
QoS & transient_local()
Set the durability setting to transient local.
Definition: qos.cpp:210
rmw_qos_profile_t & get_rmw_qos_profile()
Return the rmw qos profile.
Definition: qos.cpp:108
size_t depth() const
Get the history depth.
Definition: qos.cpp:289
rclcpp::Duration liveliness_lease_duration() const
Get the liveliness lease duration setting.
Definition: qos.cpp:316
QoS & keep_last(size_t depth)
Set the history to keep last.
Definition: qos.cpp:134
Thrown if a QoS compatibility check fails.
Definition: exceptions.hpp:351
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC QoSCheckCompatibleResult qos_check_compatible(const QoS &publisher_qos, const QoS &subscription_qos)
Check if two QoS profiles are compatible.
Definition: qos.cpp:357
RCLCPP_PUBLIC bool operator==(const NetworkFlowEndpoint &left, const NetworkFlowEndpoint &right)
Check if two NetworkFlowEndpoint instances are equal.
RCLCPP_PUBLIC bool operator!=(const NetworkFlowEndpoint &left, const NetworkFlowEndpoint &right)
Check if two NetworkFlowEndpoint instances are not equal.
RCLCPP_PUBLIC Logger get_logger(const std::string &name)
Return a named logger.
Definition: logger.cpp:34
Use to initialize the QoS with the keep_all history setting.
Definition: qos.hpp:95
Use to initialize the QoS with the keep_last history setting and the given depth.
Definition: qos.hpp:101
Result type for checking QoS compatibility.
Definition: qos.hpp:310
QoSCompatibility compatibility
Compatibility result.
Definition: qos.hpp:312
std::string reason
Reason for a (possible) incompatibility.
Definition: qos.hpp:319
QoS initialization values, cannot be created directly, use KeepAll or KeepLast instead.
Definition: qos.hpp:78
QoSInitialization(rmw_qos_history_policy_t history_policy_arg, size_t depth_arg, bool print_depth_warning=true)
Constructor which takes both a history policy and a depth (even if it would be unused).
Definition: qos.cpp:54
static QoSInitialization from_rmw(const rmw_qos_profile_t &rmw_qos)
Create a QoSInitialization from an existing rmw_qos_profile_t, using its history and depth.
Definition: qos.cpp:69