0
$\begingroup$

I am using the rospy with numpy tutorial to create a publisher and subscriber that send numpy arrays to listener that uses an ApproximateTimeSynchronizer. However, I receive an error when I try to instantiate the listener:

[WARN] [1693265081.824595]: Cannot use message filters with non-stamped messages. Use the 'allow_headerless' constructor option to auto-assign ROS time to headerless messages.

So my understanding is that my message must contain a header with a time stamp. Is it possible to add a header with a timestamp to a numpy_msg? And if so, how do I this?

My message publisher construction:

from rospy_tutorials.msg import Floats
from rospy.numpy_msg import numpy_msg

l_lines_pub = rospy.Publisher('/l_lines_output', numpy_msg(Floats), queue_size=10)
r_lines_pub = rospy.Publisher('/r_lines_output', numpy_msg(Floats), queue_size=10)

l_lines_msg = np.asarray(ARRAY1)
r_lines_msg = np.asarray(ARRAY2)

l_lines_pub.publish(l_lines_msg)
r_lines_pub.publish(r_lines_msg)

And my subscriber looks like:

l_lines_sub = Subscriber('/l_lines_output', numpy_msg(Floats))
r_lines_sub = Subscriber('/r_lines_output', numpy_msg(Floats))

ats = ApproximateTimeSynchronizer([l_lines_sub, r_lines_sub], queue_size=5, slop=0.015)
ats.registerCallback(gotData)

Thanks!

$\endgroup$

1 Answer 1

1
$\begingroup$

Is it possible to add a header with a timestamp to a numpy_msg

In short, yes, I think you just need to call numpy_msg() on a stamped message.

numpy_msg() isn't a message type, it's a conversion function that creates and returns a new type based on an existing ROS message type, see here.

I have not used this myself, but it looks to me like it should work with any ROS message type that implements serialize_numpy and deserialize_numpy methods (see here). Furthermore, it appears that these two methods are auto-generated by the message generation system, and so I think you can call numpy_msg() on any ROS message, built-in or custom, including messages that include headers.

There's some more information here:

https://ros-users.narkive.com/2VzlEDxg/fast-methods-to-go-between-ros-pointcloud-and-numpy

As far as I can tell you should be able to simply replace your rospy_tutorials/Floats message with a suitable existing message or your own custom message that includes a header and a floating point array type.

The use of generic numeric arrays to pass data is discouraged, as discussed here: Stamped std_msgs, so as far as I know there's no built-in stamped generic floating-point array. You could define one, but it'd be better to define a message where the array has a meaningful name.

Curiously, the Numpy serialization and deserialization code for many built-in messages doesn't actually use Numpy, I think because a philosophy of meaningful, well-named fields tends to favor single floating-point numbers with individual names.

I found sensor_msgs/LaserScan as one example of a stamped message that does contain array fields. Corresponding (old) autogenerated Python code for that message is here. This code uses ndarray.tostring() and numpy.frombuffer() for serialization and deserialization of the ranges and intensities fields.

A similar simpler message with a Header and a float32[] or float64[] array should work with numpy_msg() and give you the timestamp you need.

listener that uses an ApproximateTimeSynchronizer. However, I receive an error when I try to instantiate the listener

Depending on what you're trying to accomplish, maybe you don't need accurate timestamps from the publisher. Then I think you could also try:

ats = ApproximateTimeSynchronizer(
      [l_lines_sub, r_lines_sub], 
      queue_size=5, slop=0.015, allow_headerless=True)

From the message_filters wiki:

If some messages are of a type that doesn't contain the header field, ApproximateTimeSynchronizer refuses by default adding such messages. However, its Python version can be constructed with allow_headerless=True, which uses current ROS time in place of any missing header.stamp field

$\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.