ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

How to create a 2D array in ROS

asked 2022-09-14 07:58:16 -0600

m0gha gravatar image

updated 2023-06-18 09:46:21 -0600

lucasw gravatar image

I want to do a custom msg as 2D array which has 4 variables. x, y, velocity, and angle. Each variable will be set to a value as 2D array. Below is the code:

matlab_file_dic = scipy.io.loadmat(map_file)
map_data_values = matlab_file_dic['mapData'][0][0][2]
map_data =  np.reshape(map_data_values,(1000,9), 'F')

for k in range(9):
    for i in range(1000):
        par_name = 'Parameters.mapData.FunctionValues[{}]'.format(k*1000 + i)
        self.model.set(par_name, map_data[i, k])

self.model.set('Parameters_INI_VALUES_COURSE_ANGLE', map_data[start_sim, 2])
edit retag flag offensive close merge delete

Comments

2

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?

ravijoshi gravatar image ravijoshi  ( 2022-09-14 09:15:49 -0600 )edit

I want to create a custom message, the message should be a 2D array " map_data[i, k] "

m0gha gravatar image m0gha  ( 2022-09-18 15:08:02 -0600 )edit
1

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.

gvdhoorn gravatar image gvdhoorn  ( 2022-09-19 02:05:39 -0600 )edit

1 Answer

Sort by ยป oldest newest most voted
2

answered 2022-09-18 22:21:23 -0600

ravijoshi gravatar image

The following two approaches can be utilized in order to create a custom message that contains a 2D array, (map_data in your case):

  1. Using nested .msg: In this approach, you define two .msg files as shown below:

    1. 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.
    2. 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
  2. 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)
  1. 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)
    
    1. 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]])
      
  2. 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.

edit flag offensive delete link more

Comments

Thanks so much. It works :)

m0gha gravatar image m0gha  ( 2022-09-20 06:08:32 -0600 )edit

Glad you made it work. Please upvote the answer and accept it by clicking on mark this answer correct.

ravijoshi gravatar image ravijoshi  ( 2022-09-20 06:15:16 -0600 )edit

Question Tools

3 followers

Stats

Asked: 2022-09-14 07:58:16 -0600

Seen: 634 times

Last updated: Sep 18 '22