Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added new costmap buffer to resize map safely #1837
Added new costmap buffer to resize map safely #1837
Changes from 2 commits
7c63041
7e926b8
a241308
51acf47
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to set to nullptr here. If you set it, it will be reset below in the update function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is necessary. If the incomingMap is called while updating the layer, and then again after the update is finished, the last call should pe processed, and the buffer emptied. Otherwise in this case the new map would be processed twice, once here, another time in the update function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If map_buffer_ is set to nullptr to begin with (you should do that in constructor's
:
), then it is only not nullptr when 259 sets it to something else. In the next function, you process the map and then reset it tonullptr
. At that point, I don't think there's any case when this is not nullptr where setting it here is necessary. You have a mutex locked above this so only this callback or one of the functions can be in use at the same time, effectively locking this variable -- unless I'm missing something.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, so both functions can call the processMap, therefore if we don't clear the map_buffer_ here, when we get to the update we see that efectively there is something in the buffer and we update it again. I think. The fact of having the lock doesn't change that: When we are here, this function has the lock, and processes the map. Then the update is waiting, and when the lock gets free, it would check the buffer, and call processMap again if it's not empty. I think you are seeing the practical case, but in theory, it would be possible to call incomingMap several times between calls to updateBounds, including during the execution of updateBounds.
But I see how this can be confusing, and tricky to follow. Maybe it's best to simply get the layered_costmap mutex at the beginning of processMap and leave the rest as it was..
I'll initialize the buffer to nullptr also, I missed that one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess let me game this out without the 262
map_buffer_ = nullptr
:map_buffer_
between the 2 functions after the mutex is released and then in the updateCosts it uses the old map since there's no processMap() call in updateCosts. Then we wait for the next iteration of the costmap to add / process the mapmap_buffer_
between the 2 functions after the mutex is released and then in the updateCosts it uses the old map since there's no processMap() call in updateCosts. Then we have a second new map before the updateBounds can be called again. If we're not in an update cycle, then that new map will be directly processed but the old map will still be stored and processed next round.You are correct, we need to set to reset in case there's something there. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just make the other changes and we should be GTG
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay I'll push the update during the day.
Just to clarify why I placed the processMap at the beginning of updateBounds and not at the end of updateCosts:
The line 168 of layered_costmap.cpp can prevent the updateCosts call from being done, which would lock the costmap if the reason for the error comes from the static_layer's map (if that would be the case, the logic would prevent the static map from being updated). By placing the processMap call at the beginning of updateBounds, we ensure that the map would be updated every time there is a new map, without any real changes on the performance of the layered costmap.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I'll fix the branch and the other changes and push during the day.
Just to clarify why I placed the call to processMap at the beginning of updateBounds and not at the end of updateCosts:
The line 168 of layered_costmap.cpp can prevent the call of updateCosts. This is problematic when the reason why we end up returning there is related to the static layer, because in that case, the incomingMap call would be prevented from updating the map (the 'update_in_progress' flag is set to true until the end of updateCosts).
It might seem like a lot of conditions should be met for that to happen, but it could happen. By moving the processMap to the beginning of updateBounds, we prevent this logic lock from happening without any performance penalty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beginning makes sense, no issue