Dynamically creating publishers in ROS2 Humble
Hello everyone,
I am pretty new to ROS and would like to get some insight into if what I am creating is good and/or viable.
The system that I am making has a Publisher Node and a unknown number of Listener nodes (the number is finite (around 5-10), but the number of them that are active will depend on the hardware configuration of the system/robot). Each Listener subscribes to their respective topic ('/topic_1', '/topic_2', '/topic_3', ...) and their ID (1, 2, 3, ...). Note, each topic name and ID will be unique and the message format for the topics is the same (I am using a custom message that I've created).
The Publisher Node has an unordered_map
unordered_map<uint8_t, rclcpp::Publisher<CustomMsgs::msg::CustomResponse>::SharedPtr> topic_table;
that holds the Listener IDs and the Publishers to their topics. The Publisher Node also advertises a service ("/set_table") that is used to add new Publishers to the topic_table.
void Publisher::SetTableCallback(const CustomSrvs::srv::SetTable::Request::SharedPtr req,
const CustomSrvs::srv::SetTable::Response::SharedPtr res)
{
auto publisher = this->create_publisher<CustomMsgs::msg::CustomResponse>(req->value, 10);
topic_table[req->id] = publisher;
// Verify if the topic has been added to the table
if(topic_table.find(req->id) == topic_table.end())
{
res->success = false;
return;
}
res->success = true;
}
The point of this is so that the Publisher Node need not have the knowledge of which Listener nodes even exist, what their topics are and only create the Publishers for the Listener nodes that are active (send the service request).
The Listener nodes only call the "/set_table" service once when they are started, meaning that adding new entries to the table will not be frequent.
Publishing to the topics will be in a separate thread of the Publisher node (The publisher node is basically used for UDP communication where the main execution thread of the node is used to send data over Ethernet and a new std::thread is created for the receiver part. I am using boost::asio for networking). When the receiver thread asynchronously receives data on the socket, the data is parsed and depending on the ID of the message, data is published on the respective topic:
topic_table[rsp_msg.id]->publish(rsp_msg);
I want to know if this type of dynamic creating of Publishers is advisable and/or safe to use and if there is maybe some better way to achieve what I intended to create. Is creating Publishers from a service callback bad practice?
Thanks in advance!