FIx wrong path segment selection in RPP and DWB#2790
FIx wrong path segment selection in RPP and DWB#2790sathak93 wants to merge 11 commits intoros-navigation:mainfrom
Conversation
…ath_segment_pr
|
@sathak93, please properly fill in PR template in the future. @SteveMacenski, use this instead.
|
|
Should I take a look at this or wait until you work on the DWB part? |
| nav2_util::geometry_utils::first_element_beyond( | ||
| transformation_begin, global_plan_.poses.end(), transform_end_threshold); | ||
|
|
||
| for (auto it = transformation_begin + 1; it != transformation_end - 1; ++it) { |
There was a problem hiding this comment.
I'm not quite understanding why this was added. It looks like a dot product finding a directional change but not really a comment about why or what problem its solving
| return euclidean_distance(robot_pose, ps); | ||
| }); | ||
|
|
||
| // Find points definitely outside of the costmap so we won't transform them. |
There was a problem hiding this comment.
I think this was the right implementation, since we want to find the first point that's outside of the statically set costmap size. This isn't an integral distance but a real-constraint distance dependent on the costmap size. This could potentially not prune quite to the end of the costmap (dropping necessary data for longer look-ahead points) for wavy paths. There's no real benefit to culling a few points more off the end of the rolling costmap window.
There was a problem hiding this comment.
if the transformed_plan is very large and has poses ahead and behind the robot as in overlapping case, the getlookahead point may select the point behind the robot making the robot leave some path and turns back immediately.
for this it is trimmed to a particular distance from transform begin using integrated distance.
if we need this to be remain unchanged, we can modify and get the lookahead point using integrated distance.
There was a problem hiding this comment.
OK that makes sense, but then this value shouldn't be derivative of the costmap size as it currently is e.g.
const double max_transform_dist = max_costmap_dim * costmap->getResolution() / 2.0;
This should probably now be a parameterized distance. max_path_dist seems like a good name.
There was a problem hiding this comment.
I agree that finding the closest point needs to have an upper bound, so that it doesn't select overlapping poses at a later part of the path. Also noting that we are implicitly relying on the lower bound given by pruning the global plan after receiving it, so we don't process the same segments twice.
There was a problem hiding this comment.
I agree with @SteveMacenski that we shouldn't prune by lookahead distance: this part of the controller happens before the lookahead distance is computed, right?
I think that we should simply prune by the minimum of the cusp distance and the costmap size. That guarantees that you won't be able to get portions of the path that have looped around.
There was a problem hiding this comment.
Yes, this happens before any of the lookahead logic is applied. This is just pruning the path forward to only consider things in a local window forward.
I don't think the lookahead_dist_ should be used here and could indeed create a problem. I think this should be a separate parameter or derived from another source.
@Aposhian I think that works. In L604-607 where we do the first_element_beyond I think the argument should change from lookahead_dist_ to the max rolling costmap size or cusp dist (and variable renamed appropriately) or a parameterizable distance. It would still have the same effect, just change the potential window to look for the nearest pose to the robot from point 0 -> costmap edge rather than point 0 -> lookahead distance which it may have passed from the last iteration if moving very fast.
| double lookahead_dist = getLookAheadDistance(speed); | ||
|
|
||
| // Check for reverse driving | ||
| if (allow_reversing_) { |
There was a problem hiding this comment.
Why remove the allow_reversing function? That is necessary so that we only do this if its appropriate to be rotating in place due to a sudden change in pose, that shouldn't normally be turned on unless letting the robot move backwards is allowable by that parameterization
There was a problem hiding this comment.
@SteveMacenski that is turned on always because this fn calculate dot product to find cusp and
https://github.com/ros-planning/navigation2/blob/5ca6c511120d4dd612d14fd944fca7eba5e19b83/nav2_regulated_pure_pursuit_controller/src/regulated_pure_pursuit_controller.cpp#L655
returns distance to cusp
if the lookahead dist is larger than cusp dist the robot will not reach the cusp.
like the goal pose, look ahead distance need to be progressively decreased when nearing the cusp.
still it won't affect the reversing behavior of the robot as this block https://github.com/ros-planning/navigation2/blob/5ca6c511120d4dd612d14fd944fca7eba5e19b83/nav2_regulated_pure_pursuit_controller/src/regulated_pure_pursuit_controller.cpp#L300
prevents the velocity to be negative in order to move backwards.
There was a problem hiding this comment.
Again, makes sense thanks for the clarification. Lets add a comment there saying that this is used to obtain the cusp point for either path following or directional changes - mostly as a note to myself later when I re-read this
|
This bug #2622 is due to either of
|
|
find_if and min_by algorithm was the main cause of the this bug. this was not suitable to overlapping path case of navthrough poses behavior. |
|
@Aposhian please let us know your thoughts 😄 |
|
I think this may relate to the fact you're giving it a hilariously small path, this is handling the looping for you so you shouldn't need to give it something so small. Though this is clearly an issue, are you sure that the controller is getting those path updates? @sathak93 why would this be? |
|
@SteveMacenski i will check this pr for very small path. also i think it is best to validate RPP of this using main branch rolling. RPP in galactic branch and in rolling branch has many differences. using rolling we can focus problems related to this pr. |
|
I think @Aposhian did use rolling's version of RPP to see that issue. I think he was just highlighting the difference with a baseline (no?) |
|
Yes, the short path that is being given has been our workaround to the bug that we are trying to fix here 😄, so that it something that we should hopefully be able to remove, but I don't think that this fix should cause a regression for short paths. I will test on nav2 |
|
I have made some modifications on my own fork. But it has occured to me: if we implement an upper bound to prevent jumping to future points, then we are implicitly increasing our reliance on the lower bound provided by the "snapping" is fine and easy for paths that don't overlap, but with overlapping paths, you need to make sure that you always prioritize earlier portions of the path over later portions, and it may be hard to do that in a deterministic but also intuitive way. There are a few ways I think we could solve this problem:
|
|
Another option would be be to get the closest waypoint between the start of |
|
@SteveMacenski I have made some modifications on my fork based off of @sathak93 's work. Should I reflect those as suggested changes in GitHub here? Or should I create another PR? |
|
I'm not entirely sure I'm following you.
Correct, but that should be pretty good, no? I haven't run into any issues w.r.t. this. We're recursively updating quickly, so there should be little change between iterations since its being run at 10-1000 hz. So as long as we can detect the robot starting pose effectively (what the role of this PR is to improve), the pruning should be spot on. I think that's safe to rely on, and in fact we already do so there's really not much change w.r.t. that.
This is where maybe your wording is confusing me. It should always select the path point that it was tracking in If I'm understanding what you mean by "snapping", you mean that it jumps to another part on the path that is technically closer, but then skips some parts of the path. That is a bug, not desired behavior (and what we're trying to fix here). I don't think anyone expects that behavior for us to want to retain it for backward compatibility. Certainly that is not a feature that we advertise or I would ever think to be desirable. Especially for a pure pursuit who's goal is to purely follow. The logic as written's goal is to find the closest point on the path that the robot is, for which it assumes perfect path tracking capability. If the path tracking is bad so that its actually closer to another part of the zig-zag, I don't think you want it to select a point that is significantly further along the route than you were in just 1 iteration prior based on that error.
Isn't what this PR is doing? But instead of a radius search, its limiting the search for what path point is most close to the robot by changing the search condition from On your diagram: I think if you look at the PR, that's the point of L604-L611's changes. We're restricting the search via the local window because we know that we're running this at 1, 5, 10, 100 hz, so its frequently. Therefore we know we shouldn't be "very far" from the last iteration so we're recursively able to update knowing we're not "far" from the last update. There's no need for the radius based search because we can just prune to only look in a local region ahead which can be set by a parameter or costmap size. The costmap size would be most useful, but that only works if you maneuvers aren't going to be squiggling multiple times within the 2x2 or 4x4 meter window. If you are making those small finite turns, we may want to instead make it based on a parameter so that it can be set lower. But for any normal system, you'd never expect to have something like what you're showing in your figure all bounded within the local costmap size. It would be a larger trend several times larger for rows / etc. But your diagram has no scale so I can't tell if you're talking about that squiggle being a 2x2m window or a 20x20m window. For configurability, maybe its a good idea to make it a parameter, but inform users in the configuration guide that a good bet for it is the costmap side length, unless making very small maneuvers that might overlap like what you're showing.
Another PR would be good and point out what you changed so its easy for me to tell on review. |
|
Sorry if my comments were confusing, since I was bringing up a few different alternatives. I do agree that parameterized closest pose is better than using a search radius, which is not as robust. I think the bound should be up to the local costmap OR the nearest turnaround point.
I suppose most users would not experience this "snapping" behavior since they use planners that always start the global plan from the current robot pose. Our planner doesn't necessarily do this, and this is why we have observed the "snapping" behavior since it just grabs the closest pose. My modifications are here: #2812 |
|
@sathak93 thank you kindly for jump starting this discussion and developing the core ideas to solve this problem. It was very clever and didn't occur to me and a few others so we really appreciate you jumping in and I hope to have your help again in the future! I'm going to close this ticket since #2812 supersedes with a slight variation on your technique to work better with another user's experiences to make sure this can work for everyone's needs |




Basic Info
Description of contribution in a few bullet points
Description of documentation updates required from your changes
Future work that may be required in bullet points
For Maintainers: