0
$\begingroup$

Rosanswers logo

I simply try to push multiple vector<double> into the message format, but can not figure it out also I looked at this and this.

     std_msgs::Float64MultiArray msg;
    vector<double> vec1 = { 1.1, 2., 3.1};
    vector<double> vec2 = { 3., 4.1, 2., 3.1};

     vector<double>::const_iterator itr, end(vec.end());
    for(itr = vec.begin(); itr!= end; ++itr) {
            // how to use the pointer  *itr here? to push vec1 and vec2 into msg ?
    }

//I also want to specify the layout and tried to use some of these lines:

    msg.data.clear();
    msg.layout.dim.push_back(std_msgs::MultiArrayDimension());
    msg.layout.dim[0].size = *da;
    msg.layout.dim[0].stride = 1;
    msg.layout.dim[0].label = "typ i";


Edit: Solution
So as said below one cannot push multiple arrays(vector is basically 1D-array) into one message as originally thought. So it does not behave like a container object for multiple variables but only holds one i-D array.
To fix this I could sum up all vectors into one 2-D array and push it into the msg: The title MultiArray is quite misleading then, but once known its ok.
(I could not get to work with data.extend(..)


Originally posted by user23fj239 on ROS Answers with karma: 748 on 2016-02-15

Post score: 3


Original comments

Comment by ahendrix on 2016-02-16:
sorry for the typo. updated my answer with the correct field name.

Comment by ahendrix on 2016-02-17:
I confused the python extend() with the C++ vector's insert(). Answer updated and should work now. Note that insert() is faster than an element-by-element push, because it only expands the size of the vector once.

Comment by user23fj239 on 2016-02-18:
Explanations on insert() can be found here, furthermore this leads back to pushing multiple vectors inside the array: make all have same vec.size() and specify it in the .stride. So each row represents one vector.

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

MultiArray messages are for publishing multi-dimensional arrays; not for publishing multiple arrays within the same message.

For example, a vector or list is a one-dimensional array, and a matrix would be a two-dimensional array.

You need to set up the dim array with the dimensions of your array. For a 1-d array, one element with the length. For a 2-d array or matrix, your dim array would have two elements; one for the height of the matrix, and a second for the width of the matrix.

Once you have dim set up, you store your data in the data field in row-major order.

As an example, if you wanted to put your vec1 in a MultiArray, you would do:

vector<double> vec1 = { 1.1, 2., 3.1};
std_msgs::Float64MultiArray msg;

// set up dimensions
msg.layout.dim.push_back(std_msgs::MultiArrayDimension());
msg.layout.dim[0].size = vec1.size();
msg.layout.dim[0].stride = 1;
msg.layout.dim[0].label = "x"; // or whatever name you typically use to index vec1

// copy in the data
msg.data.clear();
msg.data.insert(msg.data.end(), vec1.begin(), vec1.end());

Originally posted by ahendrix with karma: 47576 on 2016-02-15

This answer was ACCEPTED on the original site

Post score: 6


Original comments

Comment by 2ROS0 on 2017-03-28:
Why do you need the clear() call on msg.data?

Comment by ahendrix on 2017-03-28:
It's not necessary in this example, but it's nice to clear the array if you're re-using the same message object.

$\endgroup$
0
$\begingroup$

Rosanswers logo

Here is a complete example (please edit if any mistakes found)

vector<double> vec;
while (ros::ok()){
    int i = 0;
    std_msgs::Float64MultiArray msg;
    vec = c.getvec(typ); //function which initializes the vector
    
    msg.layout.dim.push_back(std_msgs::MultiArrayDimension());  
    msg.layout.dim[0].size = vec.size();
    msg.layout.dim[0].stride = 1;
    msg.layout.dim[0].label = strings[typ+4];
    
    
    //push data into data blob
    vector<double>::const_iterator itr, end(vec.end());
    for(itr = vec.begin(); itr!= end; ++itr) {
        //cout<<*itr<<endl;
        msg.data.push_back(*itr); 
    }/**/
    
    chatter_pub.publish(msg);
    ros::spinOnce();

    //clear stuff and sleep
    vec.clear();
    loop_rate.sleep();
}

The result on rostopic echo looks like:

layout: 
  dim: 
    - 
      label: /listener_socket/orient
      size: 6
      stride: 1
  data_offset: 0
data: [35589264796691.0, 3.0, 3.0, 167.94601, 1.6419868, 0.15967418]
---

Originally posted by user23fj239 with karma: 748 on 2016-02-17

This answer was NOT ACCEPTED on the original site

Post score: 3


Original comments

Comment by james P M on 2021-11-21:
how to assign data into defined indices for example a[2] = 12.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.