How to assign an array to a ROS message in C++
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 = arrayIcreated". 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;
}
Asked by Cyber578 on 2022-11-14 16:44:48 UTC
Answers
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()
Asked by yassie on 2022-11-16 09:23:32 UTC
Comments
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.
Asked by Mike Scheutzow on 2022-11-16 20:10:14 UTC
Comments