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

mathematical calculation on 2D matrix(Implementation of 2 nested for loop )

asked 2015-06-16 22:23:00 -0500

Fi gravatar image

updated 2015-06-17 07:43:35 -0500

Hi all; As I understand, the 2D matrix in the ROS in not available until now and for this reasn, a definition of a msg that its variable is a msg of 1D should be done. But, I would like to know how I can implement the following code: 1-define a 2D matrix named mat[m][n]; (m*n)

I write the following messages: array 2d.msg and array 1d.msg. Is it a problem in my definition?

array2d.msg
array 1d[] mat;

array 1d.msg 
int8[] a;

2- Implementation of 2 nested for loop The one of simple code for do some mathematical calculation on matrix is presented in the following:

for (i=starti; i<m, i++)  
  for (j=starti; j<n, j++)
    {mat[i][j]=mat[i+1][j]+2;}

Clearly, what I want to do is to do some mathematical functions on elements of matrix named mat. I write the simplest code of mathematical calculation in the previous lines. It is your kindness if you translate these lines to ROS code to give an idea to how to implement mathematical calculation with elements of 2D matrix.

Thanks for your help;

Fi

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2015-06-17 08:02:42 -0500

updated 2015-06-19 14:58:57 -0500

The multi-array messages in std_msgs are very useful for sending matrices. All of these message definitions include a MultiArrayLayout message and just a simple array. For example, check out the definition of the Float32MultiArray. The MultiArrayLayout describes the size and shape of the matrix. This allows a node receiving one of these messages to properly unpack the array into a multidimensional array without requiring a priori knowledge of the matrix structure.

If you are trying to do mathematical calculations on those matrices in C++, it's probably worth checking into using a standard package for matrix math such as Eigen.

EDIT

As requested, I've written a few simple demos. The demo consists of a Python script that fills out a 3x3 matrix using random integers in [0,10) and publishes that matrix as a Float32MultiArray on the /sent_matrix topic. There is then a C++ receiver that listens to that topic. In the callback I first access a few elements of the message using the formula in the MultiArrayLayout documentation, and I then convert the entire message into an Eigen::MatrixXf . Once I have that Eigen matrix I do a few simple matrix math operations and print them to the terminal. Finally I attempt to implement the nested for loop that was described in the original question. The entire ROS package is available at this gist: https://gist.github.com/jarvisschultz...

The relevant Python code for filling out the matrix is below:

mat = Float32MultiArray()
mat.layout.dim.append(MultiArrayDimension())
mat.layout.dim.append(MultiArrayDimension())
mat.layout.dim[0].label = "height"
mat.layout.dim[1].label = "width"
mat.layout.dim[0].size = 3
mat.layout.dim[1].size = 3
mat.layout.dim[0].stride = 3*3
mat.layout.dim[1].stride = 3
mat.layout.data_offset = 0
mat.data = [0]*9

dstride1 = mat.layout.dim[1].stride
offset = mat.layout.data_offset
while not rospy.is_shutdown():
    for i in range(3):
        for j in range(3):
            num = random.randrange(0,10)
            mat.data[offset + i + dstride1*j] = num

The relevant C++ code for performing the original question could be boiled down to:

void matrixcb(const std_msgs::Float32MultiArray::ConstPtr& msg)
{
    float h = msg->layout.dim[0].size;
    float w = msg->layout.dim[1].size;
    std::vector<float> data = msg->data;
    Eigen::Map<Eigen::MatrixXf> mat(data.data(), h, w);
    Eigen::MatrixXf newmat = mat;
    for (int i=0; i<h-1; i++) 
        for (int j=0; j<w; j++) 
            newmat(i,j) = mat(i+1,j)+2;
    std::cout << "newmat = " << std::endl << newmat << std::endl;

    return;
}
edit flag offensive delete link more

Comments

Thanks Jarvi Would you please write the code for simple aboving example code by MultiArray to have a better understand of it?

Fi gravatar image Fi  ( 2015-06-17 13:38:30 -0500 )edit

Thanks Javri; Would you please give me an example of using Eigen to work with matrix?

Fi gravatar image Fi  ( 2015-06-18 14:42:00 -0500 )edit

Thanks Jarvi for sharing the code. I really appreciate it. However, i"m thinking if there is any solution that can run faster than this method. Running them in the for loop might take time esp in image pixel where the resolution is high. Again, thank you. If eventually, the data in std_msgs/Float32MultiArray Message will be in one dimensional data, i wonder what's the point of using Float32MultiArray. Appreciate it if you can enlighten me. Thanks

okkewei gravatar image okkewei  ( 2023-05-23 00:14:24 -0500 )edit

@okkewei the Float32MultiArray is a generic ROS message for arbitrarily-sized matrix data. If you are looking for a standardized, generic message then this might fit the bill. If you have a more specific use-case you can always create your own messages. If you are specifically working with images (as mentioned in the comment), you probably should be working with, for example, sensor_msgs/Image (which also stores the rows/columns/channels of an image as a single one-dimensional array). Storing multidimensional arrays as "vectors" and then just keeping track of how to map the entries is a very common technique not just for serialization/transmission (like in the ROS messages), but also for working with the arrays in memory. For example, that's exactly how Eigen or OpenCV stores an Eigen::Matrix or a cv::Mat, respectively.

jarvisschultz gravatar image jarvisschultz  ( 2023-06-12 17:17:09 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2015-06-16 22:23:00 -0500

Seen: 1,142 times

Last updated: Jun 19 '15