0
$\begingroup$

I have a class which I'm using to handle topics which could be of a variety of different types. I know the topic name, but I can't necessarily infer the type of the topic from its name. Also, having to do a bunch of imports on types which I might load seems excessive.

I can go through all available topics using

import argparse
from ros2cli.node.strategy import NodeStrategy
with NodeStrategy(argparse.Namespace()) as node:
    for (
        topic,
        topic_type,
    ) in node.daemon_node.get_topic_names_and_types():
        if topic == requested_topic:
            requested_type_str = topic_type[0]

Once that's done, I have the topic type as a string like my_custom_package/msg/MyCustomMessage. How can I convert this string to a type?

In ros1, this was possible with

roslib.message.get_message_class(overlay_type_str)

edit in response to Tully to try and remove the X-Y problem:

The specific situation is that I have a series of messages which look like this:

std_msgs/Header header
bool use_default
bool default_value
string[] graph_ids
bool[] values

The message associates an edge or node in a graph with some information of a certain type. Each message has a different type for the values and default_value fields. If we could do something like generics with messages, these two fields would be generic. As I understand it that's not possible, so I have different messages for each type that I want to use.

When I publish messages of this type, I enforce that they are published into a specific namespace, e.g. /my_system/message_series, so I might have a few topics which look like

/my_system/message_series/poses # Pose type
/my_system/message_series/visits # Int type
/my_system/message_series/edge_weights # Float type
/my_system/message_series/edge_lengths # Float type

Because they are namespaced like this, I refer to these topics internally only with poses, visits and so on. My goal is to create an object which handles subscriptions to any topic in this namespace, where I can pass only the shortened name. The subscription handler can take the shortened name and create a subscriber without needing to know the type. It also has some conveniences like storing the last message and a few other things, encapsulating subscriber-related things. The object which creates this subscription handler object knows the actual type it is interested in and handles everything else.

I'm porting a system from ros1 to ros2 and so need to maintain the existing structure. But open to suggestions for better approaches to this sort of thing in ros2.

$\endgroup$
2
  • $\begingroup$ This sounds like it find be getting into X-Y question territory. Can you edit it to clarify a bit more of your motivation. I suspect there's a better approach. $\endgroup$ Commented Feb 3 at 20:59
  • $\begingroup$ Thanks for the comment, I've edited to add some detail about the specific problem. I would be interested to know if there are better approaches to this sort of thing, at least for future reference. $\endgroup$ Commented Feb 4 at 12:53

1 Answer 1

0
$\begingroup$

To convert a message type string like my_custom_package/msg/MyCustomMessage into the actual type which can then be instantiated, you can use the get_message function in rosidl_runtime_py.utilities, which contains various functions for message conversion.

In this case, it would look something like this:

import argparse
from ros2cli.node.strategy import NodeStrategy
import rosidl_runtime_py.utilities

with NodeStrategy(argparse.Namespace()) as node:
    for (
        topic,
        topic_type,
    ) in node.daemon_node.get_topic_names_and_types():
        if topic == requested_topic:
            requested_type_str = topic_type[0]


topic_type = rosidl_runtime_py.utilities.get_message(requested_type_str)
print(topic_type) # would print something like <class 'my_custom_package.msg._my_custom_message.MyCustomMessage'>)
```
$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.