What is best practice for setting a QoS profile in a rclcpp publisher or subscriber?
The Problem (in short)
I want to create a variety of rclcpp publishers and subscribers with a particular Quality of Service profile. I have found code and explanations that show how to create a QoS struct from the rmw
library. I have also found some code that I think works to convert this to a rclcpp::QoS
, so that it can be input to a publisher or subscriber object. But does this code do what I think it's doing? And what is best practice here?
I'm using ROS2 Foxy for reference.
The Problem (in full)
Let's say I have some QoS profile (below) that follows the examples in qos_profiles.hpp. I know I need to convert this to a rclcpp::QoS
object to input it to any ROS2 publisher or subscriber (in this example I'm using a Tf broadcaster).
#include "rclcpp/rclcpp.hpp"
#include "rmw/types.h"
#include "rclcpp/qos.hpp"
#include "tf2_ros/transform_broadcaster.h"
static const rmw_qos_profile_t my_custom_qos_profile =
{
RMW_QOS_POLICY_HISTORY_KEEP_LAST,
5,
RMW_QOS_POLICY_RELIABILITY_RELIABLE,
RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL,
RMW_QOS_DEADLINE_DEFAULT,
RMW_QOS_LIFESPAN_DEFAULT,
RMW_QOS_POLICY_LIVELINESS_SYSTEM_DEFAULT,
RMW_QOS_LIVELINESS_LEASE_DURATION_DEFAULT,
false
};
class myNode: public rclcpp::Node
{
std::shared_ptr<tf2_ros::TransformBroadcaster> broadcaster;
void publish_transform (...)
{
// what goes here? rclcpp::QoS qos;?
broadcaster = make_shared<tf2_ros::TransformBroadcaster>(this, qos);
broadcaster->sendTransform(...);
}
}
From the code in qos.hpp I think this works:
auto qos = rclcpp::QoS(
rclcpp::QoSInitialization::from_rmw(my_custom_qos_profile),
my_custom_qos_profile);
There is plenty of documentation on the QoS policies, but the documentation for this code is very minimal. So my questions are:
- Does this code do what I think it does and copy across the full contents of mycustomqos_profile?
- What method is best practice? E.g. should I even be using the
rmw_qos_profile_t
type to hold this information? - Why does
QoSInitialization
exist? And what is its purpose beyond aiding the initalization ofrclcpp::QoS
?
Thanks in advance for any advice or explanation.
Asked by M@t on 2021-04-20 00:21:34 UTC
Answers
I think the intened way is something like this:
#include <rmw/qos_profiles.h>
#include <rclcpp/qos.hpp>
// [...]
auto qos = rclcpp::QoS(rclcpp::KeepLast(1), rmw_qos_profile_sensor_data);
Where all the standard profiles are defined in here https://github.com/ros2/rmw/blob/master/rmw/include/rmw/qos_profiles.h
You may also use the convenience constructor for rclcpp::QoS
(https://docs.ros2.org/foxy/api/rclcpp/classrclcpp_1_1QoS.html#ad7e932d8e2f636c80eff674546ec3963) and simply modify the policy via the setting modification functions:
auto qos = rclcpp::QoS(1); // or rclcpp::KeepAll();
qos.<modifier>();
References
https://docs.ros2.org/foxy/api/rclcpp/classrclcpp_1_1QoS.html#a98fb6b31d7c5cbd4788412663fd38cfb https://docs.ros2.org/foxy/api/rclcpp/structrclcpp_1_1KeepLast.html https://docs.ros2.org/foxy/api/rclcpp/structrclcpp_1_1QoSInitialization.html#details
Asked by Fellfalla on 2022-06-28 08:01:48 UTC
Comments
Partial answer to Q1 at least:
As per this ROS answer, you can see the QoS profile of any topic by adding
--verbose
. E.g.Asked by M@t on 2021-05-06 20:21:31 UTC