Skip to content

Conversation

@omeletteee
Copy link

What:
Created a new box blur filter that can be applied to a gridmap layer to assist the rover in determining the traversability of terrain by smoothing over noise and holes.

Why:
The built-in box blur function the rover had been using previously was inefficient, so this new algorithm was created with the intention of reducing latency.

How:
This increased efficiency is achieved by using a separable algorithm in place of the naive implementation that was used previously. The gridmap layer inputLayer_ of mapIn is first blurred along the horizontal axis, and then blurred again, vertically before being returned in mapOut as outputLayer_. The function also takes in a blur radius (in units of cells, not distance), which is typically set to one but can be expanded.

Testing:
This code has been tested using the Jetson and the Zed camera, and the results have been compared against the old algorithm to find that they produce highly similar results (with the only differences being found along the edge of the map depending on what mode the old algorithm's edge handling was set to).

Other Notes:
Any potentially unclear lines should be commented in the code, but do let me know if there's anything I need to clarify.
In the future, it would be possible to use weighted averages during the blurring process in order to achieve a Gaussian blur as opposed to a box blur (unweighted) were that to become necessary.

@omeletteee omeletteee requested a review from ConnorNeed January 19, 2026 21:46
@omeletteee omeletteee self-assigned this Jan 19, 2026
Copy link
Member

@ConnorNeed ConnorNeed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Good use of header documentation. Your implemtation file could use less redundant comments.

return false;
}

if (radius_ < 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (radius_ < 0) {
if (radius_ <= 0) {

mapOut.add(this->outputLayer_);
mapOutHorz.add(this->outputLayer_);

HorizontalBoxBlur(mapIn[inputLayer_], mapOutHorz[outputLayer_], radius_); //Blurs input layer from mapIn horizontally, saves blurred values to mapOutHorz on outputLayer_
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary comment. If future coders need to understand what that function does they should look at the header file

mapOutHorz.add(this->outputLayer_);

HorizontalBoxBlur(mapIn[inputLayer_], mapOutHorz[outputLayer_], radius_); //Blurs input layer from mapIn horizontally, saves blurred values to mapOutHorz on outputLayer_
VerticalBoxBlur(mapOutHorz[outputLayer_], mapOut[outputLayer_], radius_); //Blurs outputLayer_ from mapOutHorz vertically, saves blurred values to mapOut on outputLayer_
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here


HorizontalBoxBlur(mapIn[inputLayer_], mapOutHorz[outputLayer_], radius_); //Blurs input layer from mapIn horizontally, saves blurred values to mapOutHorz on outputLayer_
VerticalBoxBlur(mapOutHorz[outputLayer_], mapOut[outputLayer_], radius_); //Blurs outputLayer_ from mapOutHorz vertically, saves blurred values to mapOut on outputLayer_
//Box blur complete!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is generally assumed that when a function returns it is complete.

//ensuring that max and min cells in radius do not exceed dimensions of gridmap layer
int minCoeff = std::max(0, x - r);
int maxCoeff = std::min(width - 1, x + r);
int numHoles = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally you want to count what you are interested in. We don't really care about the number of holes. We care about the number of valid values. I would rename this to be numValues.

}

template <typename T>
void BoxBlurFilter<T>::VerticalBoxBlur(const Eigen::MatrixXf &layerIn, Eigen::MatrixXf &layerOut, int r)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments apply as above

template <typename T>
void BoxBlurFilter<T>::HorizontalBoxBlur(const Eigen::MatrixXf &layerIn, Eigen::MatrixXf &layerOut, int r)
{
int height = layerOut.rows();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int height = layerOut.rows();
const int height = layerOut.rows();

void BoxBlurFilter<T>::HorizontalBoxBlur(const Eigen::MatrixXf &layerIn, Eigen::MatrixXf &layerOut, int r)
{
int height = layerOut.rows();
int width = layerOut.cols();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int width = layerOut.cols();
const int width = layerOut.cols();

for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
//ensuring that max and min cells in radius do not exceed dimensions of gridmap layer
int minCoeff = std::max(0, x - r);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int minCoeff = std::max(0, x - r);
const int minCoeff = std::max(0, x - r);

for (int x = 0; x < width; x++) {
//ensuring that max and min cells in radius do not exceed dimensions of gridmap layer
int minCoeff = std::max(0, x - r);
int maxCoeff = std::min(width - 1, x + r);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int maxCoeff = std::min(width - 1, x + r);
const int maxCoeff = std::min(width - 1, x + r);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants