Because robots need performant software
Software domains:
Robots I worked with:
Throughput: can you process your sensor data in real time?
Latency: how long does it take to react?
Closed-loop control: how fast is your loop?
Bill of Material: how powerful does your hardware need to be?
"Can I run my algorithm on a GPU?"
"That feeling when your software runs 2x faster"
Use std::vector<>::reserve()
std::vector<size_t> v;
v.reserve(100);
for(size_t i=0; i<100; i++)
{
v.push_back(i);
}
Example: improving The RealSense ROS driver
// BEFORE: this list was created and populated at each frame
std::list<unsigned> valid_indices;
// AFTER: create this vector only once and re-use it (after clean)
// The memory is allocate only once and iteration is faster
std::vector<unsigned> valid_indices;
SmallVector: a data structure that pre-allocates a certain number of elements in the stack (not the heap).
Implementations:
Avoid std::list, prefer std::deque or boost::circular_buffer
Change: remove std::map and use std::vector instead
std::vector<double> LUT_cos;
std::vector<double> LUT_sin;
double angle = angle_minimum;
for(int i=0; i<scan_distance.size(); i++)
{
LUT_cos.push_back( cos(angle) );
LUT_sin.push_back( sin(angle) );
angle += angle_increment;
}
// ----- The efficient scan conversion ------
std::vector<double> scan_distance;
std::vector<Pos2D> cartesian_points;
cartesian_points.reserve( scan_distance.size() );
for(int i=0; i<scan_distance.size(); i++)
{
const double dist = scan_distance[i];
double x = dist*LUT_cos[i];
double y = dist*LUT_sin[i];
cartesian_points.push_back( Pos2D(x,y) );
}
Example: polar to cartesian transform in LaserScan
// index in a matrix is usally calculated as:
index = column * num_rows + row;
// Nice and readable...
for( size_t y = y_min; y < y_max; y++ )
{
for( size_t x = x_min; x < x_max; x++ )
{
matrix_out( x,y ) = std::max( mat_a( x,y ), mat_b( x,y ) );
}
}
// ...But considerably faster
for(size_t y = y_min; y < y_max; y++)
{
size_t offset_out = y * matrix_out.rows();
size_t offset_a = y * mat_a.rows();
size_t offset_b = y * mat_b.rows();
for(size_t x = x_min; x < x_max; x++)
{
size_t index_out = offset_out + x;
size_t index_a = offset_a + x;
size_t index_b = offset_b + x;
matrix_out( index_out ) = std::max( mat_a( index_a ), mat_b( index_b ) );
}
}
Optimization opportunity iterating over a large 2D matrix.
Simply used
boost::sort::spreadsort::integer_sort
instead of
std::sort