-
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
graceful_controller: implement iterative selection of control points #4795
base: main
Are you sure you want to change the base?
Conversation
A few other things noted when porting to UBR-1:
|
Codecov ReportAttention: Patch coverage is
|
fb7c29e
to
76c3de6
Compare
Signed-off-by: Michael Ferguson <[email protected]>
Signed-off-by: Michael Ferguson <[email protected]>
76c3de6
to
d9ec380
Compare
Signed-off-by: Michael Ferguson <[email protected]>
This was the updated config for testing this on the UBR-1 (moving from the version of graceful controller in my repo): mikeferguson/ubr_reloaded@a24ad85 |
Note for posterity: I did also test "allow_backward" - and it still works |
Notes on things that are still different versus my controller (that maybe we'd want to do in the future):
|
Signed-off-by: Michael Ferguson <[email protected]>
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 admit, this was reasonably hard for me to review with the diffs and reordering of the main code, so I'm not 100% confident in not having missed something on an initial look. I'll probably need another complete read through after changes to sanity check.
@ajtudela since this touches the docking code and I know you're thinking about these areas - want to review / test?
nav2_graceful_controller/include/nav2_graceful_controller/graceful_controller.hpp
Outdated
Show resolved
Hide resolved
nav2_graceful_controller/include/nav2_graceful_controller/parameter_handler.hpp
Outdated
Show resolved
Hide resolved
double dist_to_goal = nav2_util::geometry_utils::calculate_path_length(transformed_plan); | ||
|
||
// If we've reached the XY goal tolerance, just rotate | ||
if (dist_to_goal < goal_dist_tolerance_ || goal_reached_) { |
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.
Why isn't this considering if we want to rotate to the goal using the prefer_final_rotation
parameter?
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.
So, there are really two different features at work here:
-
prefer_final_rotation
is actually the feature down on L212 - when we are close to the goal (less than max lookahead) and prefer final rotation, we will force the target_pose heading to be the "heading to target pose" (imagine robot is at 0,0,0 and the target_pose is 0.1,0,1.57 - if you feed this into the control law, you take a massive sweeping arc to try and approach that 1.57 heading straight on. Instead, we use atan2(0.0, 0.1) and will end up doing no sweeping turn and then just turning in place at the end). I've found this to be probably the most important feature for actually successfully following the majority of paths regardless of the planner than generated them (and especially true for planners that are not kinematics aware). -
When you've reached the XY goal, if
prefer_final_rotation
is true you probably have a huge heading error - but even if you aren't preferring final rotation you might have a small heading error (usually, we satisfy the heading requirement before we satisfy XY - but, if your localization is a bit unstable, that may not be the case). In either case, the control law gets quite unstable when the XY error is so small, and it can generate huge swooping motions to correct the heading, so you really ALWAYS want to do that final bit of rotation when you are already sitting on top of your goal.
In some ways, this second part is like the latch_xy_goal_tolerance
behavior that other controllers have - in my controller, I actually had that parameter, and goal_reached_
(as this code calls it) wouldn't be set to true, but rather to latch_xy_goal_tolerance
. Regardless, in the existing graceful_controller outside nav2, you always entered this rotation behavior even if latch and prefer were set to false - you just wouldn't have it be sticky unless latch was true.
I'm curious about your thoughts from the ticket brainstorming #4115 (comment) (or is the wobbling here more or less gone with this method recomputing at the full rate?) |
I expect most of the wobbling will be gone since our motion_target can be so much farther away in most cases |
I don't think this affects the docking code at all, because that is only using the SmoothControlLaw - which is unmodified |
14ee149
to
81a9983
Compare
@SteveMacenski all review comments have been addressed - this is ready for another look when you get a chance |
Signed-off-by: Michael Ferguson <[email protected]>
81a9983
to
11c4b15
Compare
Of course I'll test it on our robots on Monday morning. This part doesn't change the controller of the docking but this is exactly the behaviour I need for the new following server. I'll have to figure out how to integrate this part into the server reusing most of the code. |
I tested the improvements with the UBR-1 this morning. Although I don't really like the new order of the "steps" (rotation before movement, control, final rotation, ...) because it's harder (for me) to read, I have to admit that these changes take care of the wobbling much better than before. Tomorrow I'll test all the combinations for the new parameters to make sure I haven't missed anything. I recorded a little video if you want to see the changes in motion: new_graceful.mov |
What are you running for the k_phi/k_delta parameters with the controller? I found that the defaults in the controller right now are pretty aggressive on heading correction (which causes both wobbling, and divergence from the path - which appears to be also causing lots of replanning for you). I went with lower values that were actually the defaults in https://github.com/mikeferguson/graceful_controller: GracefulController:
plugin: "nav2_graceful_controller::GracefulController"
v_linear_min: 0.1
v_linear_max: 1.0
v_angular_max: 2.8
v_angular_min_in_place: 0.6
max_lookahead: 1.25
initial_rotation: true
initial_rotation_tolerance: 0.25
prefer_final_rotation: true
# The defaults aren't as good as this (more wiggling)
k_phi: 2.0
k_delta: 1.0
beta: 0.4
lambda: 2.0
# This isn't quite comparable to using actual acceleration limits
# (but works well in practice)
slowdown_radius: 0.75 I didn't update these defaults - at first thinking it might impact some people's docking servers - but upon further review, it looks like that isn't the case (the docking server has it's own parameter set). @SteveMacenski thoughts? Should we update the defaults here? |
Yes, they might be a bit high. I used these: Graceful:
plugin: nav2_graceful_controller::GracefulController
transform_tolerance: 0.5
motion_target_dist: 1.2
initial_rotation: true
initial_rotation_min_angle: 0.75
final_rotation: true
allow_backward: false
k_phi: 3.0
k_delta: 2.0
beta: 0.4
lambda: 2.0
v_linear_min: 0.1
v_linear_max: 1.0
v_angular_max: 5.0
slowdown_radius: 0.5 But I agree with you. I had to lower k_phi/k_delta for the docking server. I'd try with these settings tomorrow. |
I think I might have actually been the one who chose those higher values for the docking server initially - that is an application where you want the robot to come at the charge dock as straight-on as possible, so the values make sense for docking. I think they are too high for general navigation controlling (but it wasn't something I caught back when we originally added the controller here) |
I made a new video this morning. Lowered k_phi/k_delta reduces the wobble more. new_graceful_02.mov |
@SteveMacenski bumping this - wasn't sure if you maybe missed my comment that this was ready for another review |
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 found that the defaults in the controller right now are pretty aggressive on heading correction (which causes both wobbling, and divergence from the path - which appears to be also causing lots of replanning for you).
but upon further review, it looks like that isn't the case (the docking server has it's own parameter set). @SteveMacenski thoughts? Should we update the defaults here?
I think I might have actually been the one who chose those higher values for the docking server initially - that is an application where you want the robot to come at the charge dock as straight-on as possible, so the values make sense for docking. I think they are too high for general navigation controlling (but it wasn't something I caught back when we originally added the controller here)
We can change those, definitely! I want all defaults to have a really nice out of the box experience to showcase algorithm's values without the need of heavy tuning for 'most' applications.
declare_parameter_if_not_declared( | ||
node, plugin_name_ + ".slowdown_radius", rclcpp::ParameterValue(1.5)); | ||
declare_parameter_if_not_declared( | ||
node, plugin_name_ + ".initial_rotation", rclcpp::ParameterValue(true)); | ||
declare_parameter_if_not_declared( | ||
node, plugin_name_ + ".initial_rotation_min_angle", rclcpp::ParameterValue(0.75)); | ||
node, plugin_name_ + ".initial_rotation_tolerance", rclcpp::ParameterValue(0.25)); |
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.
That's pretty tight - we'd stop whenever the angle is > 14 deg off. I don't think that's a sensible default behavior to have the robot stop that much. Is that what's causing all the halt and rotates in the video that @ajtudela posted?
Maybe the value before of ~43 deg was too high? But I think this is definitely too low
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.
An initial rotation only happens when a new plan arrives - I suppose if you have continuous replanning running, this would be a problem - but is that the default out of the box?
} | ||
} | ||
|
||
throw nav2_core::NoValidControl("Collision detected in trajectory"); |
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.
Or also that there is no path further away than params_->min_lookahead
. I don't see how that is gracefully handled for short paths (or very long lookaheadsv for larger robots like tractors)
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.
Once the goal is < max_lookahead away, we stop enforcing the requirement that target distance > min_lookahead
* update defaults * rename to in_place_collision_resolution Signed-off-by: Michael Ferguson <[email protected]>
f3e9500
to
c35f252
Compare
Basic Info
Description of contribution in a few bullet points
final_rotation
has been renamed toprefer_final_rotation
.final_rotation
is done a bit - this is closer to how thegraceful_controller
did it. Whenprefer_final_rotation
is true, we ignore the rotation of the final pose in the path and drive straight towards (and then do an in-place rotation). Previously, this code was simply usingfinal_rotation
as "do we latch and rotate", which is only half the battle if you aren't using a kinematically aware planner.Description of documentation updates required from your changes
motion_target_dist
parameter with two new parameters:min_lookahead
andmax_lookahead
.final_rotation
toprefer_final_rotation
(to matchgraceful_controller
and also indicate that this doesn't actually ensure there is a final rotation, just that the controller will prefer to generate one if it is collision free)initial_rotation
and doubleinitial_rotation_min_angle
withinitial_rotation_tolerance
which is a better name for what this parameter does (and avoids needing two parameters to do one thing). This also involved a number of tests updates to ensure thatinitial_rotation_tolerance
cannot conflict withallow_backward
.v_angular_min_in_place
to make sure that rotation commands actually work.twist.angular.x
Future work that may be required in bullet points
These will be done before this converts from DRAFT:
There is a TODO around returning cmd_vel when TF fails - this seems like the wrong thing to do, need to look at it closer- updated this to throw, similar to no command foundReview parameterThis is consistent with other controllers in nav2max_robot_pose_search_dist
- seems to be a potentially VERY large number?For Maintainers: