2
$\begingroup$

I am trying to publish a rospy.msg.AnyMsg by doing the following:

import rospy
.
.
.
publisher = rospy.Publisher('jason_topic',
                            rospy.msg.AnyMsg,
                            queue_size=10)

publisher.publish(ros_message)

I get the following stack trace:

Traceback (most recent call last):
  File "subscriber_any.py", line 26, in <module>
    publisher.publish(ros_message)
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/topics.py", line 879, in publish
    data = args_kwds_to_message(self.data_class, args, kwds)
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/msg.py", line 118, in args_kwds_to_message
    if len(data_class._slot_types) == 0:
AttributeError: type object 'AnyMsg' has no attribute '_slot_types'

I did a print(dir(rospy.msg.AnyMsg())) and verified that there was no attribute _slot_types. Is what I am trying to do possible and if so how?

$\endgroup$

2 Answers 2

1
$\begingroup$

This is not how AnyMsg is intended to be used, and I wouldn't expect it to be possible to do this. As the error message shows, AnyMsg is missing key attributes that are required for being published: it's only useful for subscribers, so you can subscribe to anything and access the raw data. AnyMsg is usually not the tool you want to be using, though. If you have the message you want to use, you should use it.

If your goal is to publish to a topic when you don't have the message beforehand, you can:

  1. Subscribe to the topic using AnyMsg
  2. Use this newly constructed subscriber to get the topic's message type
  3. Use this message type to construct a publisher
  4. Use genpy to dynamically construct the message

...But you probably don't need (or want) to do anything that complicated: just use the correct message type whenever possible.

$\endgroup$
5
  • $\begingroup$ Is genpy strictly a command line tool? $\endgroup$
    – jasonsf
    Commented Nov 27, 2023 at 20:00
  • $\begingroup$ genpy is not a command line tool, no: it's a python library that does some of the behind-the-scenes ROS message generation for python. See docs.ros.org/en/noetic/api/genpy/html/index.html $\endgroup$
    – cst0
    Commented Nov 27, 2023 at 21:07
  • $\begingroup$ Do you know of an example of how to use genpy to dynamically construct the message? Would I have to import the genpy.Message type classes? $\endgroup$
    – jasonsf
    Commented Nov 28, 2023 at 14:58
  • $\begingroup$ I don't know of one, but if you ask a question about how to 'publish on a ros topic when the message type is not known' and link it here, I'll make a python snippet and provide it. $\endgroup$
    – cst0
    Commented Nov 29, 2023 at 18:44
  • $\begingroup$ here is the link. link $\endgroup$
    – jasonsf
    Commented Nov 30, 2023 at 19:20
0
$\begingroup$

This is not possible. Only fully defined message types can be published, as the ROS middleware requires each topic to have a fixed message type. Once a type is established for a topic, attempts to use a different type will fail (something like Could not process inbound connection: topic types do not match). You have 2 options:

  1. Use a fully defined message type if possible.

  2. If your data is truly dynamic, i.e. if the data schema is not fixed, then you can do something like using std_msgs/String with the data field being arbitrary JSON data. You would have to convert your message into JSON first though.

import rospy
from rospy_message_converter import json_message_converter
from std_msgs.msg import String

pub = rospy.Publisher(
    'jason_topic', String, queue_size=10
)
pub.publish(
    data=json_message_converter.convert_ros_message_to_json(msg)
)

I would strongly recommend option (1) because most ROS tooling cannot handle things like option (2). I would only use option (2) if you're sending arbitrary unstructured blobs over messages.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.