导航到点
这个行为树实现了:ref:behavior_trees 上的行为树的一个明显更成熟的版本。它在自由空间中从一个起点导航到一个单点目标。它既包含在特定子上下文中使用自定义恢复,也包含用于系统级故障的全局恢复子树。它还为用户提供了在返回失败状态之前多次重试任务的机会。 [校准@混沌无形]
这个 ComputePathToPose
和 FollowPath
BT节点都指定了它们要使用的算法。按照惯例,我们用它们的算法风格来命名它们 (例如,不是 DWB
,而是 FollowPath
),这样行为树或应用程序开发人员就不必担心技术细节。他们只想使用路径跟随控制器。 [校准@混沌无形]
在此行为树中,我们尝试重试整个导航任务6次,然后将任务失败状态返回给调用方。这使得导航系统有足够的机会尝试从故障情况中恢复或等待瞬态问题通过,例如来自人员的拥挤或临时传感器故障。 [校准@混沌无形]
在名义上的执行中,这将每秒重新规划路径并将该路径传递给控制器,类似于 Nav2行为树 中的行为树。然而,这一次,如果规划器失败了,它将在其子树中触发上下文感知的恢复,从而清除全局成本地图。可以在此处添加其他恢复以进行其他特定于上下文的恢复,例如尝试其他算法。 [校准@混沌无形]
同样,控制器具有相似的逻辑。如果失败,它还会尝试清除影响控制器的局部成本地图。值得注意的是反应性回退中的 GoalUpdated
节点。当一个新目标通过先占权传递给导航系统时,这允许我们退出恢复条件。这确保了当一个新目标被发布时,即使最后一个目标在试图恢复时,导航系统也会立即做出非常灵敏的反应。 [校准@混沌无形]
如果这些上下文的恢复失败,这个行为树就会进入恢复子树。这个子树是为系统级故障保留的,以帮助解决诸如机器人被卡住或在一个坏地方的问题。这个子树也有 GoalUpdated
BT节点,它每次迭代都运行,以确保新目标的响应能力。接下来,恢复子树将恢复: 成本地图清除操作、旋转、等待和备份。在子树中的每个恢复之后,将重新尝试主导航子树。如果继续失败,则运行恢复子树中的下一次恢复。 [校准@混沌无形]
虽然这个行为树没有利用它,但是 PlannerSelector
、 ControllerSelector
和 GoalCheckerSelector
行为树节点也是有帮助的。这些行为树节点将允许用户通过ROS话题动态地改变导航系统中使用的算法,而不是对要使用的算法 ( GridBased
和 FollowPath
) 进行硬编码。相反,在最有用和最独特的情况下,使用具有指定算法的条件节点创建不同的子树上下文可能是可取的。然而,选择器节点可以成为一种有用的方式,从外部应用程序而不是通过内部行为树控制流逻辑来改变算法。最好通过行为树方法来实现更改,但是我们知道许多专业用户都有外部应用程序来动态更改其导航器的设置。 [校准@混沌无形]
<root main_tree_to_execute="MainTree">
<BehaviorTree ID="MainTree">
<RecoveryNode number_of_retries="6" name="NavigateRecovery">
<PipelineSequence name="NavigateWithReplanning">
<RateController hz="1.0">
<RecoveryNode number_of_retries="1" name="ComputePathToPose">
<ComputePathToPose goal="{goal}" path="{path}" planner_id="GridBased"/>
<ReactiveFallback name="ComputePathToPoseRecoveryFallback">
<GoalUpdated/>
<ClearEntireCostmap name="ClearGlobalCostmap-Context" service_name="global_costmap/clear_entirely_global_costmap"/>
</ReactiveFallback>
</RecoveryNode>
</RateController>
<RecoveryNode number_of_retries="1" name="FollowPath">
<FollowPath path="{path}" controller_id="FollowPath"/>
<ReactiveFallback name="FollowPathRecoveryFallback">
<GoalUpdated/>
<ClearEntireCostmap name="ClearLocalCostmap-Context" service_name="local_costmap/clear_entirely_local_costmap"/>
</ReactiveFallback>
</RecoveryNode>
</PipelineSequence>
<ReactiveFallback name="RecoveryFallback">
<GoalUpdated/>
<RoundRobin name="RecoveryActions">
<Sequence name="ClearingActions">
<ClearEntireCostmap name="ClearLocalCostmap-Subtree" service_name="local_costmap/clear_entirely_local_costmap"/>
<ClearEntireCostmap name="ClearGlobalCostmap-Subtree" service_name="global_costmap/clear_entirely_global_costmap"/>
</Sequence>
<Spin spin_dist="1.57"/>
<Wait wait_duration="5"/>
<BackUp backup_dist="0.15" backup_speed="0.025"/>
</RoundRobin>
</ReactiveFallback>
</RecoveryNode>
</BehaviorTree>
</root>