Hi all!
I’m currently working with multiple robots using lidar and imu sensors for navigation, and a custom plugin to simulate DC motors in the wheels. It is part of a project involving Hardware In the Loop with ros2 controllers, and it is very important to do it through custom plugins. Anyways, you will see that this problem is extendable to more use cases, so it is not help or bug, but a topic to discuss.
The issue
Sensors like lidar and imu get their default topic like “/world/name_of_world/model/name_of_model/…” and that is perfect for running multiple worlds at the same time in a distributed way. Perfect.
The problem arises when including either a system plugin, like the DiffDrive, or a custom plugin. They have default topics starting by “/model/name_of_model/…”, which is fine too if you are only running one world at a time. If you wanted to keep the “/world…” automatic naming rule, you would have to include it in the source code of the plugin, because sdf doesn’t allow parameters. However, the world name isn’t available in a model plugin easily. You can navigate to a parent entity only if they are defined in the same sdf (as far as I tried).
If you use the ros_gz_sim create node to load models in your world, each with its unique name, you want each robot model with its model plugins in a model sdf file (no world, just the model), and you surely want each robot using its default topics so that they are coupled to the new model name (I don’t know if gazebo classic had wildcards or similar to include in the sdf, like name).
The actual problem
Now I have a set of topics starting by “/world…” and another set starting by “/model…”, and I want to connect them with ros2. If I use gz_ros_bridge I can launch two bridges, one with namespace “/world…name_of_model/” and one with namespace “/model/name_of_model/”, then I include parameter expand_gz_topic_names set to true and it is succesfully connected to ros2.
What if I want topics from different sets to be connected to the same ros2 node? I can not use a different namespace for each topic in the same node, but those topics have different namespaces.
I think it’s a topic to be discussed
Consistency in the topic is important for every case involving sensors and plugins in a multi-robot simulation. Both naming rules are useful and have their own advantages, but not choosing one single rule has a disadvantage: Not being able to use namespaces to connect ros2 nodes with all topics published by a simulated model.
I write this here because I think it’s a limitation that could be fixed from the source code and could benefit more users. Below I explain the workarounds I found to solve it in an “ugly” manner.
My workarounds
- I saw some cases of parametric sdf construction using embeded ruby here (links are broken to the example cases) and here. With that, you could specify in each sensor the topic element in the sdf sensor or plugin definition, having any of the naming rules in a clean manner.
- Remappings in the ros_gz_bridge apply only to the ros2 topics. If you remap one nomenclature to the other, it is unified in the ros side. It’s tricky since remapping doesn’t allow to mix strings with launch arguments, and having the whole topic name with the new namespace applied and with a type acceptable by remappings requires a lot of string construction from arguments, static parts (words like “model” or “world”) and yaml input.
- Building a transport bridge that either removes or adds the world part at the beginning of certain topics. If it is a world plugin, it has access to the world name. I haven’t tried it, but with the ros_gz_bridge yaml file and a service that receives the model names, it could work.