Search code examples
arraysdynamiceloquentsaveros

Save dynamic size of Ros messages in arrays


I use the Ros-Yolo neural network for image recognition. I want to store the received bounding boxes which I receive through the Ros-Yolo neural network in an array. Each position of the array should be the following struct.

struct rectangle_box {
  long x_max;
  long y_max;
  long x_min;
  long y_min;
};

Since the number of received bounding boxes can vary constantly I need a dynamic array. My question is now which procedure is more sensible.

  1. is it more useful to create a dynamic array of type of the above mentioned struct which adjusts its size with every new received message. For example with the malloc() function.
  2. or is it more useful to create an array which I define big enough to store always enough bounding boxes. For example: std::array <rectangle_box, 1000> bounding_box_in_pixel;

But I need to be able to access the stored bounding boxes globally.

Here is my callback which receive the bounding boxes data

void callback_baunding_box (const darknet_ros_msgs::msg::BoundingBoxes::SharedPtr bounding_boxes_msgs)
{


}

This is how I would solve it for the second case.

struct rectangle_box {
  long x_max;
  long y_max;
  long x_min;
  long y_min;
};

std::array <rectangle_box, 1024> bounding_boxes_in_pixel;

void callback_baunding_box (const darknet_ros_msgs::msg::BoundingBoxes::SharedPtr bounding_boxes_msgs)
{
  for (unsigned long i = 0; i < bounding_boxes_msgs->bounding_boxes.size(); i++)
  {
    bounding_boxes_in_pixel.at(i).x_max = bounding_boxes_msgs->bounding_boxes.at(i).xmax;
    bounding_boxes_in_pixel.at(i).y_max = bounding_boxes_msgs->bounding_boxes.at(i).ymax;
    bounding_boxes_in_pixel.at(i).x_min = bounding_boxes_msgs->bounding_boxes.at(i).xmin;
    bounding_boxes_in_pixel.at(i).y_min = bounding_boxes_msgs->bounding_boxes.at(i).ymin;
  }
}

Thanks for the help in advance


Solution

  • There are several ways to to this. Have a look at this very simple suggestion:

    Create a vector with the maximum size of elements you are expecting. This allocates a single block of memory for your items under the hood.

    std::vector<rectangle_box> bounding_boxes_in_pixel(1024);
    

    At each callback, resize your vector. Shrinking the size will not lead to reallocation. This means, that increasing the size again (not bigger than it was before) will also not lead to reallocation (see this question).

    void callback_baunding_box (const darknet_ros_msgs::msg::BoundingBoxes::SharedPtr bounding_boxes_msgs)
    {
        //Resize
        bounding_boxes_in_pixel.resize(bounding_boxes_msgs->bounding_boxes.size());
        //Continue to fill
        ...
    }
    

    Sure, resizing the vector does also take some minimal time (basically to check and set the new size variable) under the hood. But I think this should be acceptable since the solution is very simple and easy to understand.