The following two approaches can be utilized in order to create a custom message that contains a 2D array, (map_data
in your case):
Using nested .msg: In this approach, you define two .msg files as shown below:
Create Row.msg
file with the following content:
int8[] data
- Here, you create a row of your map.
- Please note that, I am assuming that map contains data of type
int8
. Please change it as per your need.
Create Map.msg
file with the following content:
Row[] row
- Here, you append the above created row to your msg.
- Please check the following link for more info. #q67273
- Using flattened array: In this approach, you reshape your 2D array to make it a 1D array. This is the simplest approach and used by ROS to publish images (2D data). You are free to check the message definition of sensor_msgs/Image and read more about it.
Example
Consider you have the following 2D array:
In [1]: map_data
Out[1]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]], dtype=int8)
Approach #1: Create every row and append it to map as shown below:
# initialize map
map = Map()
# initialize row with 1D data
row1 = Row([ 0, 1, 2, 3])
# append row to map
map.row.append(row1)
row2 = Row([ 4, 5, 6, 7])
map.row.append(row2)
row3 = Row([ 8, 9, 10, 11])
map.row.append(row3)
NumPy Simulation:
In [2]: row1 = np.array([ 0, 1, 2, 3])
In [3]: row2 = np.array([ 4, 5, 6, 7])
In [4]: row3 = np.array([ 8, 9, 10, 11])
In [5]: map_data_received = np.vstack((row1, row2, row3))
In [6]: map_data_received
Out[6]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
Approach #2: Just flatten your data and publish it. Upon subscribing, reshape it back to 2D as shown in the NumPy simulation below:
In [6]: map_data.flatten()
Out[6]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
In [7]: map_data_received = map_data.flatten().reshape((3,-1))
In [8]: map_data_received
Out[8]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
On a side note, it seems that your variable map_data_values
is already a 1D array. So, approach #2 can be applied directly.
The question is hard to understand. Do you want to create a custom message? Furthermore, I could not understand the relation of your code snippet with the title of your question. Can you please provide more information?
I want to create a custom message, the message should be a 2D array " map_data[i, k] "
Just to make it extra clear: there is no such thing as an "Nd array" (with
N > 1
) in ROS msg IDL. It's not supported.The best you can do is use one of the work-arounds suggested/described by @ravijoshi in his answer below.