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

How to assign an array to a ROS message in C++

asked 2022-11-14 15:44:48 -0500

Cyber578 gravatar image

updated 2022-11-16 06:41:42 -0500

Hello, I am very new to C++ so this might be somewhat of a simple syntax question but I really don't know the keyword to look up or how to search for this problem. Similar topic in the forum does not seem to solve my problem. Basically what I want to do is to create an array of type Uint8 and assign a value to each element of the array, then publish it to a topic (in this case "chatter").

If I assign an array directly to msg.data (Ex. msg.data = {2,1,0};) then the node publish array of [2,1,0] as expected but if I create an array and assign value to it, why can't I say "msg.data = array_I_created". Is there a way to assign an array to msg so that ROS can publish it?

Thank you very much. Any help would be appreciated.

The code is as follows:

#include "ros/ros.h"
#include "std_msgs/UInt8MultiArray.h"

int main(int argc, char **argv)
{
ros::init(argc, argv, "talker");
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise<std_msgs::UInt8MultiArray>("chatter", 1000);
ros::Rate loop_rate(10); 

while (ros::ok())
  { std_msgs::UInt8MultiArray msg;
    uint8_t image[5][2]; //create an array and assign value to each element
    int i = 0;
    int j = 0;
    for (i = 0; i<5; i++){
        for(j = 0; j<2; j++){
            image[i][j] = i;
            }
      }
    //msg.data = {2,1,0}; //if assign directly like this, it works but why the below doesn't?
    msg.data = image //this gives an error
    chatter_pub.publish(msg);
    ros::spinOnce();
    loop_rate.sleep();
  }
 return 0;
 }
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
0

answered 2022-11-16 08:23:32 -0500

yassie gravatar image

This is a C++ issue and not really ROS-related. Your problem is the line

uint8_t image[5][2]

You're creating a 2D array of dimensions 5x2, not a 5-element 1D array filled with 2s that you and the message type are expecting. Google C-style array initialisation for more detail. Using the {2, 1, 0} syntax is fine, since the compiler automatically resolves that down to a 3-element 1D array with elements 2, 1 and 0.

Workaround is to use C++ vectors rather than raw arrays (protip: prefer to use std::vector over C-style arrays unless you have a good reason not to). The following should do the trick

std::vector<uint8_t> image(5, 2) // this actually does intialise a 5-element vector with 2s
...
msg.data = image.data()
edit flag offensive delete link more
0

answered 2022-11-16 19:10:14 -0500

Mike Scheutzow gravatar image

In roscpp, messages natively support a field that is a single-dimension array. The c++ class for this ros message will implement the field using a std::vector<t>() object. Do a web search to learn how to store objects in a std::vector.

The class in your example, std_msgs::UInt8MultiArray() is a little odd. It was created in order to fake a multiple-dimension array using an array with only a single dimension.

See http://wiki.ros.org/Messages and http://wiki.ros.org/msg for more information about the field types in a ros message.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2022-11-14 15:44:48 -0500

Seen: 905 times

Last updated: Nov 16 '22