-
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
Enable goals to be sent in other frames than the pre-configured global_frame #3917
Conversation
…r frames than the pre-configured global_frame (map) Addresses ros-navigation#3894, at least partially.
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 generally approve of both of these actions - but is this exhaustive? It seems to me that potentially other updates wrt global_frame
could be made to other BT nodes. I don't want to only partially solve the issue. From my eye quickly glancing at the BT nodes that may also directly benefit from this change:
nav2_behavior_tree/plugins/condition/goal_reached_condition.cpp
Outdated
Show resolved
Hide resolved
The transform between map and odom (the typical global and local frames) can change over time, so it is actually important to update the path each iteration to account for drift / odometric motion. Can you clarify what you think is implicit and might be desired to disable?
Absolutely, yes. This is a known thing since they do analogous operations. They're meant to be used mutually exclusively or where the behavior tree has definitionally "more liberal" definitions of reached-ness than the controller server's (in whatever definition is sensible for the formulation of the Goal Checker). That, at least, is my intent with it. If there's a better way to homogolate them (perhaps make the GoalReached condition send a service request to the controller server's goal checker?), I'm all ears. This is potentially to be used outside of the usual path-tracking modes though; for instance if doing some kind of control loop in the BT itself independent of the Controller/Planner servers Also linter is unhappy
|
@meyerj its been 2 weeks - can you please respond to the review so we can get this resolved? |
Maybe "implicit" is not the right word: What I meant is that some action servers transform the goals (or whatever input pose?) only once initially, and others keep looking up the transform continuously in each update cycle, like the controller. I think the behavior is fine as-is and no extra parameter is needed. But the navigator actions now transform the goal(s) only once initially, although multiple replanning steps may be triggered while running the behavior. Those decisions do have an effect on the behavior if the goals are not provided in the respective pre-configured frame, and hence would be worth to be mentioned in the documentation somewhere? Or was that even by design that another trigger of the planner action (e.g. |
I think we've beaten this topic with a stick. You should navigate with respect to some external frame. This is standard practice but certainly an explicit remark about it does not hurt in documentation, I would agree. Use |
nav2_behavior_tree/plugins/action/remove_passed_goals_action.cpp
Outdated
Show resolved
Hide resolved
With those small updates, this looks good to go to me! Please |
Not necessarily imho: It only implies that the transformation to the internal frame needs to happen only once early on, when the goals are received and before buffer timeouts could occur, as it is done with this patch now. rviz for example sends goal poses in whatever frame is selected as the fixed frame, and with a "now" timestamp. (Remeber to run rviz with the |
…to fix/goal-frame-id
…oals behavior nodes (ros-navigation/navigation2#3917) (#489)
That's also what you could do with the request; transform it into odom frame and send it. That's SOP. See things like the spin/backup behaviors.
That is not a correct understanding of the intent, but may be able to be leveraged in the way you describe. A zero timestamp says to use the most recently available transformation in TF transformations when its transformed, not to do so every single time in all cases where TF is looked up. That is again, incredibly fragile and highly not recommended. So many of the things needed to make robotics highly accurate after you hit a POC level comes down to time synchronization and properly propagating timestamps. |
…l_frame (ros-navigation#3917) * nav2_behavior_tree/nav2_bt_navigator: enable goals to be sent in other frames than the pre-configured global_frame (map) Addresses ros-navigation#3894, at least partially. * Address review comments (ros-navigation#3917 (review)) * Address more review comments (ros-navigation#3917 (review)) * Make uncrustify happy using cuddle braces for single line if statements... * Fix removed global_frame input for the GoalReached node in the unit test
…l_frame (ros-navigation#3917) * nav2_behavior_tree/nav2_bt_navigator: enable goals to be sent in other frames than the pre-configured global_frame (map) Addresses ros-navigation#3894, at least partially. * Address review comments (ros-navigation#3917 (review)) * Address more review comments (ros-navigation#3917 (review)) * Make uncrustify happy using cuddle braces for single line if statements... * Fix removed global_frame input for the GoalReached node in the unit test Signed-off-by: gg <[email protected]>
…l_frame (ros-navigation#3917) * nav2_behavior_tree/nav2_bt_navigator: enable goals to be sent in other frames than the pre-configured global_frame (map) Addresses ros-navigation#3894, at least partially. * Address review comments (ros-navigation#3917 (review)) * Address more review comments (ros-navigation#3917 (review)) * Make uncrustify happy using cuddle braces for single line if statements... * Fix removed global_frame input for the GoalReached node in the unit test Signed-off-by: enricosutera <[email protected]>
…l_frame (ros-navigation#3917) * nav2_behavior_tree/nav2_bt_navigator: enable goals to be sent in other frames than the pre-configured global_frame (map) Addresses ros-navigation#3894, at least partially. * Address review comments (ros-navigation#3917 (review)) * Address more review comments (ros-navigation#3917 (review)) * Make uncrustify happy using cuddle braces for single line if statements... * Fix removed global_frame input for the GoalReached node in the unit test
This patch was meant to address the issue described in #3894, at least partially: Some ROS and behavior tree nodes do not check the header frame_id of the goal and assume that goals are provided in their respective global frame.
I tested this patch with our own setup for an Ackermann-steered quad-like robotic platform, and also with the
tb3_simulation_launch.py
from the Getting Started guide. While this patch does solve the issue for the former, unfortunately I could not reproduce the issue with the latter though. We are using thenav2_smac_planner/SmacPlannerHybrid
planner and thenav2_regulated_pure_pursuit_controller::RegulatedPurePursuitController
with thenavigate_w_replanning_only_if_path_becomes_invalid.xml
behavior tree, so a different setup than the Turtlebot example setup.Basic Info
-
tb3_simulation_launch.py
from the Getting Started guideDescription of contribution in a few bullet points
The stamped goal pose will be transformed to the configured
global_frame
of thebt_navigator
node inNavigateToPoseNavigator::initializeGoalPose()
before initialization of the BehaviorTree blackboard.The following behavior nodes maintained in this repository consume the
goal
input and may be affected:ComputePathToPose
ComputePathToPose
action server (planner_server
) in the action request.planner_server
transforms a goal to its own global frame, if that would differ from the global frame of thebt_navigator
node. Otherwise the transform by theplanner_server
is a no-op.NavigateToPose
NavigateToPose
action server (bt_navigator
) in the action request.NavigateToPose
action, that would be a recursion?GoalReached
bt_navigator
node, then thegoal
on the blackboard was already transformed to the global frame before now, and the change inGoalReachedCondition::isGoalReached()
would not strictly be necessary because thegoal.header.frame_id
and the global frame do already match. However, because the input of this node is a stamped goal pose and it may also be used in other contexts, I suggest to do the comparison in the goal's frame in any case. The value readglobal_frame
is redundant and only applied if thegoal.pose.frame_id
is empty.Description of documentation updates required from your changes
Future work that may be required in bullet points
Apply a similar patch to
NavigateThroughPosesNavigator
, for consistency?The
planner_server
does already transform the goal point(s) to the global frame here and here, since Fix #2186 #2222. However, thecontroller_server
does not and it depends on the controller implementation whether the transform to the local frame is applied only once upon receiving a new plan or continuously, at each call ofcomputeVelocityCommands()
. It also transforms the goal pose to the local frame (the "global frame" of the local costmap) inControllerServer::isGoalReached()
(since Bugfix tf lookup of goal pose in nav2_controller #2780).In case of the
controller_server
not transform the goal path initially may be desirable, because updates of the transform between the global and local frame are supposed to have a direct effect on the controller for a path provided in map coordinates, without the need to replan. But maybe it would be good to document this implicit behavior better? Or even to add a parameter and optionally transform the received path only once, inControllerServer::computeControl()
?The configured goal checker used by the controller server may disgree with the behavior tree's
GoalReachedCondition
, which is only based on the Euclidian 2D distance. Depending on the concrete behavior tree this may have unwanted implications? However, I noticed that this condition node is not even used by any of the behavior trees innav2_bt_navigator
, so this concern cannot be the culprit of the behavior described in Goal frame_id is not respected consistently #3894.For Maintainers: