0
$\begingroup$

Rosanswers logo

Hi all, I am trying to send an array of vector from one node to another node as a message. The message contains this array and other message fields as well.

My cpp file has the following array vector:

 Vector<Point> distancePoints[11];

The above array of vector is the one I need to publish and subscribe.

For example, distancePoints[0] contains vector< Point > from distance 1m and so on. Point contains x and y coordinates. Point is an opencv 2D point class.

Is it possible to publish and receive such array of vector using ROS messages? Does anyone have an idea about how it can be done? What will be the structure of message header?


Originally posted by rosusernli on ROS Answers with karma: 52 on 2017-10-19

Post score: 1

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

Hello,

I've created a new message to do that, including an array and another field, just to show how you can do that.

The command to create the package: catkin_create_pkg my_pkg roscpp std_msgs geometry_msgs

The message definition (my_pkg/msg/my_msg.msg)

geometry_msgs/Point[] points
uint8 another_field

In the my_pkg/package.xml file, don't forget to add the dependencies for generating the messages:

  <build_depend>message_generation</build_depend>
  <run_depend>message_runtime</run_depend>

my_pkg/CMakeLists.txt file:

cmake_minimum_required(VERSION 2.8.3)
project(my_pkg)

find_package(catkin REQUIRED COMPONENTS
  geometry_msgs
  roscpp
  std_msgs
  message_generation
)

## Generate messages in the 'msg' folder
add_message_files(
  FILES
  my_msg.msg
#   Message2.msg
)

## Generate added messages and services with any dependencies listed here
generate_messages(
  DEPENDENCIES
  geometry_msgs#   std_msgs
)

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES my_pkg
   CATKIN_DEPENDS geometry_msgs roscpp std_msgs message_runtime
#  DEPENDS system_lib
)

include_directories(
  ${catkin_INCLUDE_DIRS}
)

add_executable(my_publisher src/my_publisher.cpp)
add_executable(my_subscriber src/my_subscriber.cpp)

add_dependencies(my_publisher ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(my_subscriber ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(my_publisher ${catkin_LIBRARIES})
target_link_libraries(my_subscriber ${catkin_LIBRARIES})

Finally, the publisher and subscriber files:

my_pkg/src/my_publisher.cpp

#include "ros/ros.h"
#include "geometry_msgs/Point.h"
#include "my_pkg/my_msg.h"

#include <vector>

struct Point {
    float x;
    float y;
};

int main(int argc, char **argv)
{
  // ROS objects
  ros::init(argc, argv, "my_publisher");
  ros::NodeHandle n;
  ros::Publisher pub = n.advertise<my_pkg::my_msg>("my_topic", 1);
  ros::Rate loop_rate(0.5);
  
  // the message to be published
  my_pkg::my_msg msg;
  msg.another_field = 0;
  
  // creating the vector
  Point my_array[11];
  Point point;
  for (int i=0; i < 11; i++) {
    point.x = i;
    point.y = i;
    my_array[i] = point;
  }
  std::vector<Point> my_vector (my_array, my_array + sizeof(my_array) / sizeof(Point));
  
  // loop control
  int count = 0;
  while (ros::ok())
  {
    msg.points.clear();
    
    msg.another_field = count;
    int i = 0;
    for (std::vector<Point>::iterator it = my_vector.begin(); it != my_vector.end(); ++it) {
        geometry_msgs::Point point;
        point.x = (*it).x;
        point.y = (*it).y;
        point.z = 0;
        msg.points.push_back(point);
        i++;
    }
  
    ROS_INFO("%d", msg.another_field);
    
    pub.publish(msg);

    ros::spinOnce();

    loop_rate.sleep();
    ++count;
  }


  return 0;
}

my_pkg/src/my_subscriber.cpp

#include "ros/ros.h"
#include "my_pkg/my_msg.h"

void clbk(const my_pkg::my_msg::ConstPtr& msg) {
    ROS_INFO("%d", msg->another_field);
    ROS_INFO("first point: x=%.2f, y=%.2f", msg->points[0].x, msg->points[0].y);
}

int main(int argc, char **argv)
{
  // ROS objects
  ros::init(argc, argv, "my_subscriber");
  ros::NodeHandle n;
  ros::Subscriber sub = n.subscribe("my_topic", 1, clbk);
  
  ros::spin();
  
}

If you want to see step-by-step, I've created a video (https://youtu.be/4eHWSXGqXg8).


Originally posted by marcoarruda with karma: 541 on 2017-10-19

This answer was ACCEPTED on the original site

Post score: 4


Original comments

Comment by gvdhoorn on 2017-10-19:\

If you have problems to compile, try to compile the message before the nodes

your CMakeLists.txt does not have any add_dependencies(..) lines. That is why build ordering may not be correct.

See the catkin docs.

Comment by marcoarruda on 2017-10-20:
Perfect, thanks for the reminder! I totally forgot about this instruction since the messages were there when I tried to compile the nodes. I'm updating the answer.

Comment by rosusernli on 2017-10-22:
Thank you for your detailed answer. It was really helpful for me. The code compiled and worked perfectly. But I was not able to reach the video link. But anyway the example code helped me to do my stuff.

Comment by Developer on 2018-06-06:
Is it possible to do same thing with service & client relation ?

$\endgroup$

Your Answer

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