Conversation
…ng of code review comments
Signed-off-by: johntgz <johntan@openrobotics.org>
…tion2 into update-costmap-on-request
… use-case Signed-off-by: johntgz <johntan@openrobotics.org>
|
@JohnTGZ, please properly fill in PR template in the future. @SteveMacenski, use this instead.
|
|
@AlexeyMerzlyakov I just realised that if we are to combine the updating and publishing of map into the |
I wonder what I might have missed out here? |
AlexeyMerzlyakov
left a comment
There was a problem hiding this comment.
Okay, good. Please check the review items for this PR and next step required - is to add a new testcase on this feature.
I think, this should be:
- New unit test for the update-on-request feature. From brief view, it could be a
Costmap2DROSclass object with preparedlayered_costmap_inside tuned on one plugin, e.g. onstatic_layer. Static layer could listen the incoming OccupancyGrid map published by simple OccupandyGrid publisher (also added inside the test). You could publish some occupancy grid once, then run Costmap2DROS until the costmap is not being published (and be equal to initial OccupancyGrid). Then update the incoming map, manually triggerupdateAndPublishMap()and check that costmap was updated correctly. If necessary, the test might containCostmap2DROSclass wrapper, inherited from base class that is you will have an access to all protected parent class fields. Also, I think, we need to check that ifupdate_on_requestis set to false, costmap is being updated automatically.
But in overall, it could be something more simpler, if you could find better way and propose instead. - Supporting "update_on_request" parameter in dynamic params test
test/integration/dyn_params_tests.cpp
There was a problem hiding this comment.
Generally speaking, this looks good to me, but heed @AlexeyMerzlyakov's comments. I'll take a look once he fully approves, but all looks good to me from a first glance.
You do have some linting issues, which CI should point out to you (or ament_cpplint / ament_uncrustify)
I just realised that if we are to combine the updating and publishing of map into the updateAndPublishMap() method, then if update_on_request is TRUE, the publish_frequency will not matter.
Is that true? Its still being used in the updateAndPublishMap() function to only publish after the duration is expired from the last publication. Isn't the publish_cycle_ still being respected? It may be not queried at the regular looping rate anymore, but should at least enforce approximate publication -- or at least not any more frequently than that.
If it is important for the costmap server to still publish with a fixed frequency, perhaps we can break the publishing out into another thread
I don't think its very important to be exactly at a fixed rate, its more about throttling than it is regularity. If you have updates to the local costmap at 20hz (which is not terribly uncommon), publishing that at 20hz is very expensive just for visualization. 5hz or something is very reasonable, instead.
I wonder what I might have missed out here?
Nothing, the macro is broken and I haven't had a time to fix it yet. Mergify keeps working for a few weeks, then breaks 🙄
On unit test: you could simply create a costmap with this parameter on with a static layer. Send it a random static map (full obstacle, a smiley face, whatever). Check that the costmap is still empty. Then trigger that update method and check that there are new values -- but on that update, not due to a regular background thread. I think that's also what Alexey described, more or less.
|
This pull request is in conflict. Could you fix it @JohnTGZ? |
|
@AlexeyMerzlyakov please rereview |
|
Hi all, sorry that I have not had time to add the test yet, I would be able to do it by friday |
There was a problem hiding this comment.
A few strokes remained:
- Please correct the logic of
updateAndPublish()call inCostmap2DROS::on_activate() - Rebase onto latest
mainbranch and correct the patch accordingly
And unit test is missing for this feature. You can take nav2_costmap_2d/test/regression/plugin_api_order.cpp as a basis: this testcase creates a new Costmap2DROS object and sets a plugin (in your case it will be static_layer) for it, then executes.
| } | ||
|
|
||
| void | ||
| Costmap2DROS::updateAndPublishMap() |
There was a problem hiding this comment.
Please rebase onto to the latest main branch: there is a new indicator variable and behavior used to verificate that Costmap2DROS was started. It ought to be added to updateAndPublishMap(), since this API logic should be called only of Costmap2DROS was already started:
void
Costmap2DROS::updateAndPublishMap()
{
if (stopped_) {
// Do not execute if start() did not complete plugins activation
return;
}
nav2_util::ExecutionTimer timer;
// Measure the execution time of the updateMap method
timer.start();
updateMap();
timer.end();
...
}
… least once when update_on_Request parameter is true Signed-off-by: johntgz <johntan@openrobotics.org>
Signed-off-by: johntgz <johntan@openrobotics.org>
|
@AlexeyMerzlyakov Thank you for the guidance and suggestions, I have made the suggested changes and added a unit test as well, please take a look when you are free :) |
|
|
||
| void waitForMap() | ||
| { | ||
| while (!this->isCurrent()) { |
There was a problem hiding this comment.
One thing that I can't quite figure out is if we still need to check if the layered costmap is current? From the static layer plugin, it is set to true after receiving a new map. I can remove this check if that is the case and just do a normal spin.
There was a problem hiding this comment.
I do not think this is a problem: another integration tests are also uses the same approach. As indicator current_ is also OK: this means that we could use the map (for static layer in this case - it was received).
| // Execute after start() will complete plugins activation | ||
| if (!stopped_) { | ||
| // Measure the execution time of the updateMap method |
There was a problem hiding this comment.
Since it have already begun to do, why not optimize some: instead of do all this stuff inside if-statement, it is better to add something like mentioned in previous comment item:
if (stopped_) {
// Do not execute if start() did not complete plugins activation
return;
}
nav2_util::ExecutionTimer timer;
// Measure the execution time of the updateMap method
timer.start();
updateMap();
timer.end();
...
Which is more readable instead of having one more indent in the code. What do you think?
There was a problem hiding this comment.
Yes, this is definitely more readable, I will make the changes.
| @@ -0,0 +1,257 @@ | |||
| // Copyright (c) 2022 Samsung R&D Institute Russia | |||
There was a problem hiding this comment.
Please, correct the copyright message to one related to you.
| #include <rclcpp/rclcpp.hpp> | ||
| #include <nav_msgs/msg/occupancy_grid.hpp> | ||
| #include <nav2_costmap_2d/cost_values.hpp> | ||
| #include <nav2_costmap_2d/costmap_2d_ros.hpp> | ||
| #include <nav2_util/occ_grid_values.hpp> |
There was a problem hiding this comment.
Please use " to address these headers as relative to the ROS/project rather than system ones
|
|
||
| void waitForMap() | ||
| { | ||
| while (!this->isCurrent()) { |
There was a problem hiding this comment.
I do not think this is a problem: another integration tests are also uses the same approach. As indicator current_ is also OK: this means that we could use the map (for static layer in this case - it was received).
|
|
||
| // Spin to check that background thread does not update the costmap | ||
| waitSome(200ms); | ||
| // rclcpp::spin_some(costmap_ros_wrapper_->get_node_base_interface()); |
There was a problem hiding this comment.
Please, remove unnecessary commented line
| publishOccupancyGrid(); | ||
|
|
||
| // Spin until the background thread updates the map | ||
| waitSome(200ms); |
There was a problem hiding this comment.
Since there is the waitForMap() call on next line, do we really need this wait?
There was a problem hiding this comment.
The issue is that without waiting for the costmap update thread to spin for at least 1/map_update_frequency, the map will not be updated by the costmap node.
void
Costmap2DROS::mapUpdateLoop(double frequency)
{
// --snip--
rclcpp::WallRate r(frequency); // 200ms by default
while (rclcpp::ok() && !map_update_thread_shutdown_) {
updateAndPublishMap();
// Make sure to sleep for the remainder of our cycle time
r.sleep();
// --snip--
}
I am not sure, how GitHub will handle correctly non-linear merges. So, it is better to force-push your branch made over latest If I did this, I would like to rename You also could verify the results by clonning https://github.com/JohnTGZ/navigation2.git in a |
Basic Info
This PR targets #3121, implement the 'update costmap on request' function via the boolean parameter
update_on_requestwhich can be specified on the costmap layer.This PR is also a continuation from #3297 , which is closed as it was supposed to be merged into the
mainbranch.Description of contribution in a few bullet points
update_on_requestparameter for the costmap serverupdateAndPublishMap()on each update loop.costmap_ros_->isUpdateOnRequest()to determine if it will need to callupdateAndPublishMap().mapUpdateThreadOff()andmapUpdateThreadOn()to make it easier to manage the map update loop thread.Description of documentation updates required from your changes
update_on_requestparameter to the costmap configuration documentation for navigation.ros.orgFuture work that may be required in bullet points
Document the use case and implications of the
update_on_requestparameter.For Maintainers:
Instructions for testing