-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Goalchecker path argument and plugin #4789
base: main
Are you sure you want to change the base?
Goalchecker path argument and plugin #4789
Conversation
Signed-off-by: Jonas Otto <jonas@jonasotto.com>
Signed-off-by: Joseph Duchesne <josephgeek@gmail.com>
…checking 3 goal checkers at once in a single method proved too unweildy. - Added tests for the new PathCompleteGoalChecker Signed-off-by: Joseph Duchesne <josephgeek@gmail.com>
@josephduchesne, your PR has failed to build. Please check CI outputs and resolve issues. |
Signed-off-by: Joseph Duchesne <josephgeek@gmail.com>
715a395
to
d90135e
Compare
@josephduchesne, your PR has failed to build. Please check CI outputs and resolve issues. |
Signed-off-by: Joseph Duchesne <josephgeek@gmail.com>
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.
A couple of followups:
- We should add in a new configuration guide page for this on docs.nav2.org. Also, a migration guide entry for the new feature!
- Is there a sensible reason why we shouldn't make this the default? I think we can update the nav2_params.yaml to always use this now & update the controller server's built-in default as well. This, I believe, is a globally better solution :-)
Generally though, this looks good to me
nav2_controller/include/nav2_controller/plugins/path_complete_goal_checker.hpp
Outdated
Show resolved
Hide resolved
nav2_controller/include/nav2_controller/plugins/path_complete_goal_checker.hpp
Outdated
Show resolved
Hide resolved
Will do.
I think this is a reasonable default. The only advantage that the existing built-in goal checkers have is that they require potentially far less math to check (which could be important on budget educational bots). I only made a new goal checker because that was what the original draft author had in his todo list :) I'll update the default in the PR. |
Signed-off-by: Joseph Duchesne <josephgeek@gmail.com>
I keep thinking that there is probably a way to use |
Signed-off-by: Joseph Duchesne <josephgeek@gmail.com>
… threshold rather than pose count. Extended tests. Signed-off-by: Joseph Duchesne <josephgeek@gmail.com>
Signed-off-by: Joseph Duchesne <josephgeek@gmail.com>
Codecov ReportAll modified and coverable lines are covered by tests ✅
|
nav2_controller/include/nav2_controller/plugins/path_complete_goal_checker.hpp
Outdated
Show resolved
Hide resolved
{ | ||
using nav2_util::geometry_utils::is_path_longer_than_length; | ||
|
||
if (is_path_longer_than_length(path, path_length_tolerance_)) { |
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 the problem here is that if the path is not updated regularly (i.e. we plan once on start and only replan if there's a problem rather than at a fixed frequency), this would not work. We actually have logic in the Controller's path handlers to account for this by finding the robot's closest point on a path within a local window size of the path and storing that as our robot's "new starting point" to prune all points prior to. Then as we iterate, that is dynamically updated. As long as the search window is larger than the greatest distance a robot can move within the control frequency plus some margin, then it works on an iterative basis.
I agree this would work fine enough though for the case that we update the path on a regular frequency as long as the tolerance is sufficiently generous.
I think it would make sense to implement the same kind of logic here, no? If so, I think we should create a nav2_util
function that does this path handling that we use here. Then, we can replace the copy-pasted version of that in all the controllers with a common util so they all behave the same! That would be a great architectural contribution
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'll see what I can do :)
@josephduchesne can you button up these last few details so we can get this in? 😄 |
@josephduchesne, your PR has failed to build. Please check CI outputs and resolve issues. |
Signed-off-by: Joseph Duchesne <josephgeek@gmail.com>
…dynamic param callack code Signed-off-by: Joseph Duchesne <josephgeek@gmail.com>
b6e59e8
to
7ba08df
Compare
@josephduchesne, your PR has failed to build. Please check CI outputs and resolve issues. |
@josephduchesne, your PR has failed to build. Please check CI outputs and resolve issues. |
I started to look into the path handler implementations to try to figure out a good approach for handling the path shortening aspect generically as you suggested. I'm not sure if I'll have time in the next few weeks to try to address that. It hadn't occurred to me that this might be a problem since while I have been working with many different controllers, I'm doing so in the context of a Nav2 BT similar to the "NavigateWithReplanning" example, containing this bit that wraps Bathe controller/planner/path interaction.
This means that aside from some slight quirks if I use very loosely defined paths + a very opinionated planner, the controller will suddenly cut corners or similar once a path goal is removed that was previously influencing intermediate steps in the planner or controller. That's not a huge problem, but interesting as an aside. Back to the design at hand. I think there's a tension around the "current_path_" use as I'm using it, how its used in controler_server.cpp computeAndPublishVelocity(), which also contains the "copy paste" you'd recommend removing (generating current_path, and perhaps ironically possibly having the exact same bug that I'm trying to fix here if the path contains loops, close zig-zags or self-intersections. The issue with implementing that in the goal checker is that the goal checker's job currently doesn't include maintaining a stateful global plan, and updating it as the robot moves. That, I think, is the Controller's job, and the current_path_ passed in to the goal checker should be one that includes only present (maybe) and future path segments, not past ones. We certainly could increase the scope of the goal checkers to be much more stateful to handle this. I'd rather move to trying to enforce a (soft) expectation that the controllers prune their paths. Either way, I'm curious to hear your thoughts since I'm jumping back into reading this code after a month away from it, and far less familiar with Nav2's implementation on the best of days. My hope would be either a clear decision that this PR requires a resolution to the global path is never updated issue, or agreement that we can split this off into its own enhancement request, and follow-up branch + PR down the road. I'm still interested in working on that either way, but I'm working on an agricultural robot that's got to be ready for the planting season, so my time is more limited the next few months. |
Signed-off-by: Joseph Duchesne <josephgeek@gmail.com>
See MPPI/RPP -- we don't search for the closest-point on the path in the full path scope but rather the closest point from a previous iteration's last point within a search window. That way, the window can be set to the maximum a robot can possibly move between iterations (plus margin) and remove the loop finding.
I don't think that's always realistic, if you only plan at 1 hz but control at 20 hz, you are naturally going to make movement between them (let alone replanning every 5-10-20 seconds). I agree however that this is annoying logic to continuously reimplement, so it might be worth building a controller util that does this that we can deploy here, MPPI, RPP, etc more easily. The versions in MPPI/RPP are slightly different, however. Perhaps an instance of the controller util, hosted by the controller server can be used by the goal checker? And/Or, the controller plugins are given both the global path and the pre-transformed and pruned path to use as their inputs, so we can remove some of the implementation details from each controller into centralized utilities that are computed in the server and then given to the plugins? I think this would move the computation of the transformed / pruned plan into the controller when calling isGoalReached so that the goal checker itself is not maintaining a path / servicing its state changes. Now, its done by the controller and the input to this function is a pre-pruned pre-transformed plan. That plan could also be given to the controllers directly, if need be/desirable. So I think the steps here:
Does that make sense? 😄 |
This is a continuation of work started by @ottojo in draft PR #4593
I'll quote their introduction and, expand a bit afterwards, and update any fields that have changed.
I've cherry-picked @ottojo 's commit on top of the latest main branch, then added a new basic goal checker PathCompleteGoalChecker, which is a subclass of SimpleGoalChecker, but has an additional parameter (path_length_tolerance, default=1), and checks that the current path has <= path_length_tolerance waypoints before allowing the normal SimpleGoalChecker completion logic to take its course.
The result is a trivial extension of SimpleGoalChecker that should be immune to the current_pose = goal_pose short-circuit problem/bug. Rather than try to create an elaborate unit test that navigates a course, I stuck to first principles to ensure that the new plugin behaves the same as SimpleGoalChecker with <= path_length_tolerance waypoints, and that it does not complete with > path_length_tolerance waypoints.
Basic Info
Description of contribution in a few bullet points
GoalChecker::isGoalReached
interface with argument for current pathDescription of documentation updates required from your changes
Future work that may be required in bullet points
For Maintainers: