-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Calculate next path point using lookahead for Graceful Controller #5003
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
Conversation
|
@SakshayMahna, your PR has failed to build. Please check CI outputs and resolve issues. |
|
@SakshayMahna, your PR has failed to build. Please check CI outputs and resolve issues. |
1 similar comment
|
@SakshayMahna, your PR has failed to build. Please check CI outputs and resolve issues. |
Codecov ReportAttention: Patch coverage is
... and 5 files with indirect coverage changes 🚀 New features to boost your workflow:
|
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.
Thinking aloud a bit:
This bit of code looks like we iterate through the path, try to find the max_lookahead distance away and back up closer and closer to the robot until we find a solution that is collision free.
Is that case, we should attempt to find the interpolated lookahead point for the max_lookahead away to start off with, that gives us the best and smoothest value.
After that point, its a bit arbitrary the distance selected, isn't it? Selecting a lookahead_resolution versus marching through the path points I don't think improves the smoothness, does it? Either way there's a discontinuity now on the distance away to use based on the collision state (unless we set the search resolution to be very fine, which is probably not computationally worthwhile).
For example, the resolution you set was 0.1, but a normal path from a planning plugin probably does it closer to 0.05 for the costmap resolution when that resolution is 5cm. So wouldn't this case actually be more coarse?
Did you test this without the lookahead_resolution feature and generate those charts using the normal path point iteration? I suspect the improvement in smoothness you see is when the max_lookahead is used due to lack of collision requiring backing up the path to finding the first valid trajectory. My intuition says that when we do the backing-up process, we own that discontinuity either way, given we're backing up by 5cm or 10cm, respectively.
nav2_graceful_controller/params/graceful_controller_params.yaml
Outdated
Show resolved
Hide resolved
nav2_regulated_pure_pursuit_controller/params/regulated_pure_pursuit_params.yaml
Outdated
Show resolved
Hide resolved
nav2_graceful_controller/include/nav2_graceful_controller/graceful_controller.hpp
Outdated
Show resolved
Hide resolved
Do you see an improvement using the By default you have it set to 0.1, but the path resolution is ~0.05. If you lower that to 0.05 or even lower like 0.02, is it smoother than before? If so, I think that's a neat feature and we can keep it, users can tune to their liking and we can set it default to the costmap resolution. If not, I think maybe we should revert that bit and only use the interpolation when using the full lookahead distance. Else, just use the path points since there's a jump anyway. |
|
No, I don't see any improvement while using a smaller lookahead resolution. The plots for the 3 cases (smaller resolution, larger resolution, using points) all look similar. |
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.
There's one superficial refactor that would in my opinion make this easier to read / understand:
// Calculate target pose through lookahead interpolation
double dist_to_target = params_->max_lookahead;
geometry_msgs::msg::PoseStamped target_pose = nav2_util::getLookAheadPoint(
dist_to_target, transformed_plan, params_->interpolate_after_goal);
bool valid_target_pose_found = validateTargetPose(target_pose, dist_to_target, dist_to_goal, local_plan, costmap_transform, cmd_vel);
if (!valid_target_pose_found) {
...
...
valid_target_pose_found = validateTargetPose(target_pose, dist_to_target, dist_to_goal, local_plan, costmap_transform, cmd_vel);
if (valid_target_pose_found) {
break;
}
}
This would remove the else statement and explicitly setting the valid_target_pose_found instead of just capturing the validate method's return.
|
@SakshayMahna can you work on these last couple of updates? |
|
Hello Steve, |
|
This pull request is in conflict. Could you fix it @SakshayMahna? |
|
Hi @SteveMacenski What I understand it is because of the fallback code that was added, that in case Lookahead Point is not found, fallback to default behaviour of checking the poses one by one. The only way I think this can be tested is by adding an obstacle in the cost map. That way, the Lookahead Point will become invalid because of collision check by What do you think about this? Any ideas to improve the code coverage? |
SteveMacenski
left a comment
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 some of these changes in refactoring will resolve the testing gap! :-)
|
This pull request is in conflict. Could you fix it @SakshayMahna? |
|
@SakshayMahna, your PR has failed to build. Please check CI outputs and resolve issues. |
|
This pull request is in conflict. Could you fix it @SakshayMahna? |
|
Hi @SteveMacenski Sorry for the mess. |
SteveMacenski
left a comment
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 have a few open comments above, but overall doesn't this look simpler and cleaner! Great work 😄
|
@SakshayMahna, your PR has failed to build. Please check CI outputs and resolve issues. |
|
This pull request is in conflict. Could you fix it @SakshayMahna? |
|
@SakshayMahna, your PR has failed to build. Please check CI outputs and resolve issues. |
Merge latest changes
|
Reverted the extra commits and pulled from main. |
|
Some of the tests are failing from these changes: |
This seems to be the issue, it doesn't update since that doesn't exist as a valid dynamic parameter so the other tests fail due to those not being updated from the failure |
Signed-off-by: Sakshay Mahna <sakshum19@gmail.com>
|
@SakshayMahna thank you for the diligence! I know that took awhile! This is a really great update though to the controller and in architecture so we don't have that duplication - thanks so much! |
|
Thank you for pushing through as well Steve! |
|
Can you expand on that? I'm not sure @SakshayMahna and I fully grokk the picture's meaning. |
| // Calculate orientation towards interpolated position | ||
| // Convert yaw to quaternion | ||
| double yaw = atan2( | ||
| point.y - prev_pose_it->pose.position.y, | ||
| point.x - prev_pose_it->pose.position.x); |
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.
@SakshayMahna this block is new compared to the version in RPP. Maybe this shuld be scrutinized?
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.
Yes, this is the problem. There is a discontinuity taking place because of which the angle comes out to be reversed (added / subtracted by pi).
The red arrow is the motion target published by the graceful controller, while the blue path is the transformed plan. I thought the head of the red arrow should be the same direction with the transformed plan If that's unclear, I will record a video tomorrow |
|
I agree it probably should be. Did you do an A-B test that this is definitely the PR that changes that behavior? |
I did, after reverting this commit, I saw the heading is always the same as the transformed plan |
|
@SakshayMahna does that make sense? Can you take a look :-) @mini-1235 do you have a reproduction example on the Tb3/4 sims that he can use as a reference to test? |
It is very late in my time zone, I will write it down here tomorrow:) |
I replace the controller plugin in nav2_params and left everything else as default: Then launch the tb3 demo I will show my result before and after this PR: Before 2025-09-12.21-21-12.mp4After 2025-09-12.21-14-55.mp4 |
|
Hi @mini-1235 , |
|
As pointed out by Steve above, the problem is in the yaw interpolation. There is a discontinuity taking place because of which the angle comes out to be reversed (added / subtracted by pi). I think I have a fix for it. Keeping the yaw value in a way to keep it in the direction of motion of robot. |
@SakshayMahna Feel free to ping me when you open the PR, I can test it :) |
|
Thank you! |
|
Love it guys - please take a look and I will too! |
…s-navigation#5003) * Add controller utils Signed-off-by: Sakshay Mahna <sakshum19@gmail.com> * Fix linting issues Signed-off-by: Sakshay Mahna <sakshum19@gmail.com> * Update regulated pure pursuit Signed-off-by: Sakshay Mahna <sakshum19@gmail.com> * Update graceful controller Signed-off-by: Sakshay Mahna <sakshum19@gmail.com> * Remove interpolate after goal & Use orientationAroundZAxis Signed-off-by: Sakshay Mahna <sakshum19@gmail.com> * Update nav2_util/src/controller_utils.cpp Signed-off-by: Steve Macenski <stevenmacenski@gmail.com> * Update nav2_util/src/controller_utils.cpp Signed-off-by: Steve Macenski <stevenmacenski@gmail.com> * Update nav2_util/src/controller_utils.cpp Signed-off-by: Steve Macenski <stevenmacenski@gmail.com> * Remove interpolate_after_goal parameter from test Signed-off-by: Sakshay Mahna <sakshum19@gmail.com> --------- Signed-off-by: Sakshay Mahna <sakshum19@gmail.com> Signed-off-by: Steve Macenski <stevenmacenski@gmail.com> Co-authored-by: Steve Macenski <stevenmacenski@gmail.com>


Basic Info
Description of contribution in a few bullet points
lookahead_resolutionandinterpolate_after_goal)Additional Information
lookahead_resolution.interpolate_after_goal.Description of documentation updates required from your changes
Description of how this change was tested
Future work that may be required in bullet points
For Maintainers: