In Python, can I initialize arrays in message without importing element types like C++ resize()?

asked 2020-08-12 06:58:46 -0500

yukimura gravatar image

updated 2020-08-18 00:04:13 -0500

In C++, I can initialize arrays in message with resize(), so I don't have to find, include or initialize element types of allay.

In Python, I initialize arrays in message as follows.

from A_msg.msg import A
from B_msg.msg import B
from C_msg.msg import C

msg_a = A()
msg_a.bs = [B()]
msg_a.bs[0].cs = [C()]
msg_a.bs[0].cs[0].data = 0

It takes time and effort to find and import element types, especially when message has multiple layers of array and contains multiples types over multiple layers.

Can I initialize arrays in message without importing element types like C++ as follow?

from A_msg.msg importA

msg_a = A()
msg_a.bs.resize(1)
msg_a.bs[0].cs.resize(1)
msg_a.bs[0].cs[0].data = 0
edit retag flag offensive close merge delete

Comments

The default constructor of a ros message already initialize all the fields of the message to 0 (or empty array), do you have a message that isn't propperly intialized ? Is msg_a = A() not working ? For example with a PolygonStamped msg, this :

B = PolygonStamped()
B.polygon.points.append(1)
B.polygon.points.append(2)
B = PolygonStamped()

Will return a PoseStamped object with all the values to 0 (and an the geometry_msgs/Point32 array will be empty too).

Delb gravatar image Delb  ( 2020-08-18 03:33:28 -0500 )edit

Messages is properly initialized. But I have difficulty in initialize sub messages contained in array of the message without importing sub messages' types.

yukimura gravatar image yukimura  ( 2020-08-18 04:49:04 -0500 )edit

B.polygon.points.append(1)

In your above example, it appears to add a integer "1" into Point32 array, don't it? Is it valid operation?

I ran the below code and got error.

code:

pub = rospy.Publisher("poly", geometry_msgs.msg.PolygonStamped, queue_size=1)
B = geometry_msgs.msg.PolygonStamped()
B.polygon.points.append(1)
pub.publish(B)

error:

File "/opt/ros/melodic/lib/python2.7/dist-packages/rospy/msg.py", line 152, in serialize_message
    msg.serialize(b)
File "/opt/ros/melodic/lib/python2.7/dist-packages/geometry_msgs/msg/_PolygonStamped.py", line 105, in serialize
    buff.write(_get_struct_3f().pack(_x.x, _x.y, _x.z))
AttributeError: 'int' object has no attribute 'x'
yukimura gravatar image yukimura  ( 2020-08-18 04:51:04 -0500 )edit

Oups my bad you are right, apparently it doesn't complain if you simply print. It was just to illustrate that when you call the message constructor everything is reset. I still don't understand your issue to be honest, you don't need to import all the sub messages but only the one you want to use with your array. In my case I should have done :

from geometry_msgs.msg import PolygonStamped
from geometry_msgs.msg import Point

B = PolygonStamped()
B.polygon.points.append(Point())

Here you don't need to import a Polygon msg but directly the message you need (Point). Sorry for the bad example.

Delb gravatar image Delb  ( 2020-08-18 05:51:36 -0500 )edit