Ask Your Question
0

Publish a numpy.array in a UInt8MultiArray in python

asked 2018-08-22 05:19:21 -0500

DRos gravatar image

updated 2018-08-22 05:23:39 -0500

Hi all,

Pretty new to python and ROS. I have a node that subscribes to some data, in the callback it then does some calculations on that data and creates a new np.array. I then want to publish this new array in a UInt8MultiArray with a fixed size so that I can receive it with another node and send it over UDP.

The example below doesn't include the calculations but the output of the code at the moment is

[[  31.41386309  292.95704286    2.44705586]]
<type 'numpy.ndarray'>

I need to send these values with a fixed length over a Uint8MultiArray so that I can pack it and send it over UDP. I've tried multiple ways but can't seem to get it to work. I was wondering if someone can help with some example code or ideas/best ways.

#!/usr/bin/env python

import rospy
from std_msgs.msg import UInt8MultiArray
import struct
import math
import numpy as np


def callback(data):
    #Calculations before to create enu with data from callback.
    enu = **
    print(enu)
    print(type(enu))
    pub_packet.publish(gps_enu)

def lla2enu():
    global gps_enu, pub_packet
    rospy.init_node('lla2enu', anonymous=True)
    rate = rospy.Rate(250) # 10hz
    rospy.Subscriber("packet", UInt8MultiArray, callback)
    pub_packet = rospy.Publisher('gps_enu', UInt8MultiArray, queue_size=10)
    rospy.spin()

if __name__ == '__main__':
    try:
        lla2enu()
    except rospy.ROSInterruptException:
        pass

Any help is much appreciated. Thanks guys.

edit retag flag offensive close merge delete

Comments

in a UInt8MultiArray with a fixed size

pedantic, but: UInt8MultiArray by definition cannot have a fixed size.

gvdhoorn gravatar imagegvdhoorn ( 2018-08-22 05:32:22 -0500 )edit

@gvdhoorn, thanks for the reply. Maybe I can manipulate the data inside enu to be of a specific size to guarantee the size of the UInt8MultiArray?

DRos gravatar imageDRos ( 2018-08-22 05:36:56 -0500 )edit

My comment was slightly unfair: I just meant to say that UInt8MultiArray uses unbounded lists for its fields, so by definition those do not have a fixed size. You can of course specify a certain size to be used, but that would be completely at the application level (and not enforced in/by ROS).

gvdhoorn gravatar imagegvdhoorn ( 2018-08-22 05:39:12 -0500 )edit

I would also think that the serialisation to your UDP packet/datagram would be orthogonal to the ROS msg type you're intending on using. If an incoming msg doesn't "fit", you could ignore it / raise an error, etc.

Also note btw: *MultiArray is an extremely bad choice for a topic. It has ..

gvdhoorn gravatar imagegvdhoorn ( 2018-08-22 05:41:13 -0500 )edit

.. absolutely no semantics associated, other than that it is a nD array with fields of a certain type.

That makes interpretation of the data completely dependent on information external to the msg, which goes against best practice in ROS.

gvdhoorn gravatar imagegvdhoorn ( 2018-08-22 05:42:31 -0500 )edit

Thanks a lot for the replies. What msg type would you recommend for a topic that just wants to publish 3 float values?

DRos gravatar imageDRos ( 2018-08-22 05:46:49 -0500 )edit

That completely depends on the semantics.

What do those values represent?

gvdhoorn gravatar imagegvdhoorn ( 2018-08-22 05:50:07 -0500 )edit

These values represent a local x,y,z value in metres.

DRos gravatar imageDRos ( 2018-08-22 05:51:41 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2018-08-22 05:33:47 -0500

gvdhoorn gravatar image

updated 2018-08-22 05:36:41 -0500

Haven't used it myself, but perhaps eric-wieser/ros_numpy can help here.

And rospy itself also has support for numpy. See rospy.numpy_msg and Using numpy with rospy fi.

edit flag offensive delete link more

Comments

Thanks for this. Using the talker example and numpy_msg(Floats) as a message type worked perfectly. Thank you!

DRos gravatar imageDRos ( 2018-08-24 04:20:13 -0500 )edit

Glad it worked for you.

Just noticed this btw in your code:

rate = rospy.Rate(250) # 10hz

250 != 10 Hz.

gvdhoorn gravatar imagegvdhoorn ( 2018-08-24 04:35:59 -0500 )edit

Ahh yes, it's carried over from another node. Poor documentation, my bad!

DRos gravatar imageDRos ( 2018-08-24 04:36:54 -0500 )edit

Also: the rate is not even being used.

gvdhoorn gravatar imagegvdhoorn ( 2018-08-24 04:38:48 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2018-08-22 05:19:21 -0500

Seen: 1,241 times

Last updated: Aug 22 '18