2016-05-17 71 views
0

我的应用程序我需要创建点云的固定大小缓冲区(3个元素)。
要做到这一点,我试图用简单的方式在我的回调(我的工作ROS):矢量缓冲区C++

vector< vector<Point2d> > points_buffer(3); // buffer of point clouds ,fixed size = 3 
void laserToWorldCallback(const icars_laser_roi::stx_points::ConstPtr& laser_points, const icars_2d_map_manager::Status::ConstPtr& car_pos){ 

double x_w, y_w; 
double x, y; 
vector<Point2d> temp; 

    for(int i = 0; i < laser_points->points_x.size(); i++){ 
     // get the coordinates 
     x = laser_points->points_x[i]; 
     y = laser_points->points_y[i]; 

     // tranform the coordinates 

     x_w = car_pos->xGlobal + x*cos(car_pos->yaw) - y*sin(car_pos->yaw); 
     y_w = car_pos->yGlobal + x*sin(car_pos->yaw) + y*cos(car_pos->yaw); 

     temp.push_back(Point2d(x_w, y_w)); 

    } 

    if(points_buffer.size() != 3){ // the buffer is not empty 
     points_buffer.push_back(temp); 
    }else{ // the buffer is empty, delete last element and push_back 

     // delete last element 
     points_buffer[0] = points_buffer[1]; 
     points_buffer[1] = points_buffer[2]; 
     points_buffer[3] = temp; 



    } 



} 
} 

但这种方式在我看来有点粗糙且无效率可言。
可能有人建议我采用更优雅高效的方式来做我想做的事情? 谢谢
Regards

+0

可以使用std :: replace方法我认为它会更加巧妙地 –

回答

1

解决一些效率问题。首先temp声明后,你已经可以保留它会与

temp.reserve(laser_points->points_x.size()); 

使用,因此不会有任何的内存重新分配push_back方法记忆。

如果您使用的是C++ 11或更高版本,如果缓冲区尚未满,您可以使用std::move移动temp的内容。

points_buffer.push_back(std::move(temp)); 

这是O(1)操作。此后有效但未指定的temp的内容。

然后在删除最后一个元素时使用vector :: swap而不是copy,因为它会交换内容并保证在时间上不变。

points_buffer[0].swap(points_buffer[1]); 
points_buffer[1].swap(points_buffer[2]); 
points_buffer[2].swap(temp); //There is a typo here index should be 2 not 3. 

如果你想在一个类中包装point_buffer,程序将更具可读性。那么你也可以考虑不旋转整个矢量的内容,但要跟踪第一个索引。这将很好地工作也较大point_buffer比3.然后加入新的元素来缓冲将只是

point_buffer[fist_element_].swap(temp); 
first_element=(first_element_+1)%3; 

然后在位置访问元素i,你可以实现operator[]作为

vector<Point2d>& operator[](int i){ 
    return point_buffer[(i+first_element)%3]; 
} 
+0

谢谢你的建议! –