Ask Your Question
0

ROS2 sending multiple inputs msg

asked 2021-05-08 10:36:29 -0600

Raoryn gravatar image

hi, im trying to send four floats like 20.0,20.0,320.0,20.0 in a msg on a publisher node, but it realy doesnt like to send the numbers.

import rclpy
# from OpenCVnodetest import cameraModule
from rclpy.node import Node

from std_msgs.msg import Float64MultiArray

class Anglepublisher(Node):
    # _camera_module = cameraModule()
    def __init__(self):
        super().__init__("maximumLikelihood")
        self.publisher_ = self.create_publisher(Float64MultiArray,'Angles',10)
        timer_period = 0.5
        self.timer = self.create_timer(timer_period,self.timer_callback)
        self.i = 0

    def timer_callback(self):
        msg = Float64MultiArray()
        msg.data = [(20.0,20.0,320.0.i,20.0)]
        self.publisher_.publish(msg)
        self.get_logger().info('Publishing: ',msg.data)
        self.i +=1

def main(args=None):
    rclpy.init(args=args)
    anglepublisher = Anglepublisher()

    rclpy.spin(anglepublisher)

    anglepublisher.destroy_node()

    rclpy.shutdown()



if __name__ == '__main__':
    main()

we have been looking at making a custom msg type but so far not successfull with finding the right type if we actualy did it the right way. is making a custom msg type the right way or does it already excist a type that works in our problem?

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
1

answered 2021-05-09 03:22:59 -0600

sgvandijk gravatar image

Testing your node shows two issues. Firstly:

AnglePublisher.py", line 18, in timer_callback
    msg.data = [(20.0,20.0,320.0.i,20.0)]
AttributeError: 'float' object has no attribute 'i'

Assuming that's a typo :) removing the .i results in your real issue:

AnglePublisher.py", line 18, in timer_callback
    msg.data = [(20.0,20.0,320.0,20.0)]
  File "/opt/ros/foxy/lib/python3.8/site-packages/std_msgs/msg/_float64_multi_array.py", line 156, in data
    assert \
AssertionError: The 'data' field must be a set or sequence and each value of type 'float'

As seen in the documentation of Float64MultiArray linked by @Spectre, the data member is a 1-dimensional array, whereas you assign a list with a tuple to it, which is akin to a 2D array. The normal way to use a MultiArray message is to flatten your data to a single array, and then to specify the original layout in the layout member, also mentioned by @Spectre.

However this is not a hard requirement. If you only ever send 4 values, and your subscribers will always expect just that, you could just send them as a flat array and ignore the layout member on both sides:

msg.data = [20.0,20.0,320.0,20.0]

If however you really want to send 'multi arrays', as in lists of multiple tuples/nested lists, and you want to make your node generic so that the size of the tuples is not fixed, you should specify the layout. For instance in the following you actually have 3 4-tuples, but the code handles any data length and size of sub-arrays:

# A 2-dimensional piece of data
data = [(20.0,20.0,320.0,20.0), (20.0,20.0,320.0,20.0), (20.0,20.0,320.0,20.0)]
# Flatten data
msg.data = [v for nested in data for v in nested]
# Specify the layout of the 2 dimensions
dim0 = MultiArrayDimension()
dim0.label = "foo"
# First dimension size is the number of nested tuples
dim0.size = len(data)
# First stride is defined as the total data size
dim0.stride = len(msg.data)

dim1 = MultiArrayDimension()
dim1.label = "bar"
# Second dimension size is the length of individual nested tuples
dim1.size = len(data[0])
# Second (last) stride is equal to the size when there is no padding
dim1.stride = dim1.size

msg.layout.dim = [dim0, dim1]

As you see this gets relatively complex, and includes things you probably don't want to care about, like strides and padding. This is a good sign that you indeed probably should make your own custom message, that has just the fields you need, with explicit names fitting your use case (e.g. angles).

edit flag offensive delete link more

Comments

thaaank you so much! was loosing some hair trying to figure this out, 30 min after reading your post it started to work.

Raoryn gravatar image Raoryn  ( 2021-05-09 07:22:55 -0600 )edit
1

answered 2021-05-09 01:11:08 -0600

Spectre gravatar image

From what I've read custom messages are encouraged from the standpoint of showing would-be users of your work the API by which they may use what you've produced. More specifically, custom messages are encouraged to be provided in their own separate package so as to isolate them from everything else.

However I think you're on the right track. You should be able to use a pre-existing Float64MultiArray message without issues.

Here's the online documentation for it: std_msgs/Float64MultiArray Message

If I had to guess based on the code you published I would say that you failed to add anything to the "MultiArrayLayout" section of the message: std_msgs/MultiArrayLayout Message

Within that message is yet another message: std_msgs/MultiArrayDimension

Try poking at that. I haven't messed with the array-variants of the std_msgs yet, but it could be that the publisher isn't happy that one of those nested message types is empty.

edit flag offensive delete link more

Comments

thank you so much! this with the other post made it work

Raoryn gravatar image Raoryn  ( 2021-05-09 07:23:48 -0600 )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

1 follower

Stats

Asked: 2021-05-08 08:51:03 -0600

Seen: 324 times

Last updated: May 09 '21