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