导航概念
本页面旨在帮助新的机器人学家熟悉移动机器人导航的概念,特别是与理解和使用该项目所需的概念相关的内容。
ROS 2
ROS 2是用于Nav2的核心中间件。如果您对此不熟悉,请在继续之前访问 ROS 2文档。
动作服务器
正如在ROS中一样,操作服务器是控制导航等长时间运行任务的常见方式。该堆栈更广泛地使用了操作,并且在某些情况下没有简单的主题接口。作为ROS 2中的开发人员,理解操作服务器更为重要。一些简单的CLI示例可以在 ROS 2文档 中找到。
动作服务器类似于规范服务服务器。客户端将请求完成某些任务,但是这个任务可能需要很长时间。一个例子是将铲子从推土机上抬起,或者让机器人向右行驶10米。
在这种情况下,操作服务器和客户端允许我们在另一个进程或线程中调用长时间运行的任务,并返回其结果的future。在这一点上,阻塞直到操作完成是允许的,但是您可能希望定期检查操作是否完成并继续在客户端线程中处理工作。由于它是长时间运行的,操作服务器还将向其客户端提供反馈。此反馈可以是任何内容,并在ROS .action
中与请求和结果类型一起定义。在推土机示例中,请求可以是一个角度,反馈可以是剩余要移动的角度,结果是一个成功或失败的布尔值以及最终角度。在导航示例中,请求可以是一个位置,反馈可以是导航所花费的时间和到目标的距离,结果是一个表示成功与否的布尔值。
可以通过在动作客户端注册回调函数来同步获取反馈和结果。也可以通过异步请求共享的 future 对象来获取它们。这两种方法都需要在客户端节点中进行回调组处理。
此堆栈中使用操作服务器通过 NavigateToPose
操作消息与最高级别的行为树(BT)导航器进行通信。它们还用于BT导航器与后续的较小操作服务器进行计算规划、控制努力和恢复的通信。每个服务器与之交互的 .action
类型在 nav2_msgs
中具有自己的独特定义。
生命周期节点和 Bond
生命周期(或管理)节点是ROS 2中特有的。更多信息可以在 这里找到。它们是包含用于启动和关闭ROS 2服务器的状态机转换的节点。这有助于确定性地处理ROS系统的启动和关闭行为。它还帮助用户以合理的方式组织他们的程序,以用于商业
当节点启动时,它处于未配置状态,只处理节点的构造函数,该函数**不应**包含任何 ROS 网络设置或参数读取。通过启动系统或提供的生命周期管理器,需要将节点转换为非活动状态。然后,可以通过经历激活阶段来激活节点。
该状态将允许节点处理信息并完全设置运行环境。配置阶段触发``on_configure()``方法,将设置所有参数、ROS网络接口,并为安全系统分配所有动态分配的内存。激活阶段触发``on_activate()``方法,将激活ROS网络接口并设置程序中的任何状态以开始处理信息。
要关闭节点,我们需要经历非激活、清理、关闭阶段,并最终处于已完成状态。这些阶段分别是停用网络接口并停止处理、释放内存、正常退出。
生命周期节点框架在整个项目中被广泛使用,所有服务器都利用了该框架。如果可能的话,使用生命周期节点是所有ROS系统的最佳惯例。
在 Nav2 中,我们使用了生命周期节点的包装器 nav2_util LifecycleNode
。这个包装器为典型的应用程序简化了生命周期节点的复杂性。它还包括一个 bond
连接,用于确保在服务器转换为上层后,它仍然保持活动状态。如果服务器崩溃,它会通知生命周期管理器并降级系统,以防止关键故障。有关详细信息,请参见 从Eloquent升级到Foxy。
行为树
行为树(Behavior trees,BT)在复杂的机器人任务中越来越常见。它们是一种由任务构成的树状结构,用于完成任务。它为定义多步骤或多状态应用程序提供了一个更具可扩展性和可理解性的框架。这与有数十个状态和数百个转换的有限状态机(FSM)相反。一个例子是踢足球的机器人。将足球比赛的逻辑嵌入到有限状态机中将会具有挑战性,并且容易出错,因为存在许多可能的状态和规则。此外,像从左、右或中间射门这样的建模选择尤其不清楚。通过使用行为树,可以创建和重用基本的原语,如“踢球”,“行走”,“走向球”,以实现多种行为。有关更多信息,请参阅 本书 的第1-3章。我**强烈**建议阅读这些章
行为树为导航逻辑提供了一种形式化结构,既可以用于创建复杂系统,又可以使用先进的工具进行验证和验证其正确性。将应用逻辑集中在行为树中,并使用独立的任务服务器(仅通过树进行数据通信),可以进行形式化分析。
在这个项目中,我们使用 BehaviorTree CPP V3 作为行为树库。我们创建可以构建成树的节点插件,放置在 BT Navigator
中。节点插件会加载到行为树中,并在解析树的XML文件时与注册的名称关联起来。此时,我们可以通过行为树进行导航。
使用此库的一个原因是它能够加载子树。这意味着Nav2行为树可以加载到另一个更高级别的行为树中,以将该项目用作节点插件。例如,在足球比赛中,可以将Nav2行为树作为"去球"节点,并作为更大任务的一部分进行球检测。此外,我们还为行为树提供了``NavigateToPoseAction``插件(以及其他插件),以便可以通过通常的操作接口从客户端应用程序调用Nav2堆栈。
其他系统也可以用于设计复杂的自主行为,例如分层有限状态机(HFSM)。选择行为树是因为它在机器人和相关行业中很受欢迎,并且用户需求较大。然而,由于Nav2具有独立的任务服务器特性,未来很容易提供一个 nav2_hfsm_navigator
包,具体取决于兴趣和贡献的情况。
导航服务器
规划器和控制器是导航任务的核心。恢复机制用于将机器人从困境中解救出来,或者尝试解决各种问题,使系统具有容错性。平滑器可用于对规划路径进行额外的质量改进。本节将分析这些概念以及它们在该项目中的用途。
规划器、控制器、平滑器和恢复服务器
该项目中有四个动作服务器,包括规划器、行为器、平滑器和控制器服务器。
这些动作服务器用于托管算法插件的映射,以完成各种任务。它们还托管算法插件使用的环境表示,用于计算它们的输出。
规划器、平滑器和控制器服务器将在运行时配置算法的名称(别名)和类型。这些类型是已注册的插件库名称,而名称则是任务的别名。一个例子是使用名称 FollowPath
的DWB控制器,因为它遵循一个参考路径。在这种情况下,所有DWB的参数将放置在该命名空间中,例如 FollowPath.<param>
。
这三个服务器会公开与其任务相对应的动作接口。当行为树触发相应的行为树节点时,它将调用动作服务器来处理其任务。服务器内的动作服务器回调将根据其名称(例如 FollowPath
)调用所选择的算法,该名称映射到特定的算法。这使用户可以将行为树中使用的算法抽象为算法类。例如,您可以拥有 N
个插件控制器来跟踪路径、对接充电器、避免动态障碍物或与工具进行接口交互。将所有这些插件放在同一个服务器上使用户能够使用单个环境表示对象,这样做会很昂贵。
对于行为服务器,每个行为也有自己的名称,然而,每个插件还会公开自己的特殊动作服务器。这是因为可能会创建各种各样的行为动作,无法共享单个简单的接口。行为服务器还包含一个用于接收控制器服务器的本地代价地图的代价地图订阅者,以计算其任务。我们这样做是为了避免多个代价地图实例的重复计算,这会消耗大量计算资源。
另外,由于行为树节点是调用动作的简单插件,因此可以创建新的行为树节点来调用其他具有不同动作类型的动作服务器。建议尽可能使用提供的服务器。如果由于插件或动作接口的原因需要新服务器,则可以使用该框架来支持。新服务器应该使用新类型和插件接口,类似于提供的服务器。需要创建新的行为树节点插件来调用新的动作服务器-然而,通过广泛使用服务器和插件,不需要对Nav2 repo本身进行分叉或修改。
如果您发现需要一个新的插件库定义或动作类型的接口,请提交工单,看看我们能否在同一接口中进行修复。
规划器
规划器的任务是计算完成某个目标函数的路径。路径也可以根据术语和所选算法称为路线。两个典型的例子是计算到目标的路径(例如从当前位置到目标)或完成覆盖(例如规划以覆盖所有自由空间)。规划器将可以访问全局环境表示以及缓冲到其中的传感器数据。规划器可以编写为:
计算最短路径
计算完整覆盖路径
计算稀疏或预定义路径上的路径
Nav2中规划器的一般任务是从当前位姿到目标位姿计算有效且可能最优的路径。然而,支持许多类别的计划和路径存在。
控制器
控制器,在ROS 1中也被称为局部规划器,是我们遵循全局计算路径或完成局部任务的方式。控制器将能够访问局部环境表示,以尝试计算用于底盘跟随的可行控制力。许多控制器会将机器人在空间中向前推进,并在
沿路径前进
使用测距仪在里程计框架中与充电站对接
进入电梯
与工具进行接口连接
Nav2控制器的一般任务是计算有效的控制力以跟随全局计划。然而,存在许多类别的控制器和局部规划器。该项目的目标是使所有控制器算法能够作为此服务器中的常见研究和工业任务的插件。
行为
恢复行为是容错系统的重要组成部分。恢复的目标是处理系统的未知或故障条件,并自主处理它们。例如,可能会出现感知系统故障导致环境表示充满虚假障碍物的情况。然后会触发清除代价地图恢复以允许机器人移动。
另一个例子是,如果机器人由于动态障碍物或控制不良而被卡住。如果允许的话,倒退或原地旋转可以使机器人从糟糕的位置移动到可以成功导航的自由空间。
最后,在发生总故障的情况下,可以实施恢复操作来请求操作员的帮助。这可以通过电子邮件、短信、Slack、Matrix等方式完成。
重要的是要注意,行为服务器可以保存任何行为,以共享对昂贵资源(如代价地图或TF缓冲区)的访问,不仅仅是恢复行为。每个行为可能都有自己的API。
平滑器
通常,与规划器搜索的路径的最佳性标准相比,路径的额外细化通常是有益的。为此引入了平滑器,通常负责减少路径的不平整和平滑突然的旋转,同时增加与障碍物和高代价区域的距离,因为平滑器可以访问全局环境表示。
在将不同的规划器与不同的平滑器结合或需要对平滑进行特定控制时,使用独立的平滑器而不是作为规划器的一部分的平滑器具有优势,例如仅对路径的特定部分进行平滑。
Nav2中平滑器的一般任务是接收路径并返回其改进版本。然而,对于不同的输入路径,改进的标准和获取方法也存在,因此可以在该服务器中注册多种平滑器。
路径点跟随
路径点跟踪是导航系统的基本功能之一。它告诉我们的系统如何使用导航来到达多个目的地。
``nav2_waypoint_follower``包含一个路径点跟随程序,具有特定任务执行器的插件接口。如果您需要前往指定位置并完成特定任务,例如拍照、拾起盒子或等待用户输入,这将非常有用。这是一个演示如何在示例应用中使用Nav2的好的应用程序。
然而,它可以用于不仅仅是一个示例应用程序。对于车队管理人员/调度员来说,有两种思路:
愚蠢的机器人;智能集中调度程序
智能机器人;愚蠢的集中调度员
首先,``nav2_waypoint_follower``完全足够创建一个面向生产的机器人解决方案。由于自治系统/调度程序在分配任务时考虑了诸如机器人姿态、电池电量、当前任务等因素,因此机器人上的应用程序只需要关注当前任务而不必担心系统的其他复杂性来完成所请求的任务。在这种情况下,您应该将路径点跟随程序的请求视为一项工作单元(例如在仓库中拣选一个物品,执行一次安全巡逻,遍历一条通道等)来执行任务,然后返回给调度程序以获取下一个任务或充电请求。在这种思路中,路径点跟随应用程序只是导航的上一步,在系统自治应用程序之下。
在第二种思路中,nav2_waypoint_follower
是一个很好的示例应用程序/概念验证,但是你真正需要的是机器人上的航路点跟踪/自主系统来更好地解决问题。在这种情况下,你应该使用 nav2_behavior_tree
包来创建一个使用导航完成任务的自定义应用程序级行为树。这可以包括检查任务进行到一半时的充电状态以返回到码头,或者处理更复杂任务中超过1个工作单元的子树。很快,将会有一个``nav2_bt_waypoint_follower``(名称可能会有所调整),它将使您更容易创建这个应用程序。在这种思路中,航路点跟踪应用程序与系统自主性更为密切相关,或者在许多情况下,就是系统自主性本身。
两者并没有优劣之分,它非常依赖于机器人所完成的任务类型、环境类型以及可用的云资源。对于特定的业务案例,通常这种区别非常明确。
状态估计
在导航项目中,根据社区标准需要提供两个主要的转换。``map``到``odom``的转换由定位系统(定位、地图构建、SLAM)提供,``odom``到``base_link``的转换由里程计系统提供。
注解
使用导航系统并不需要在机器人上使用激光雷达。也没有使用基于激光雷达的避障、定位或SLAM的要求。但是,我们提供了使用激光雷达的这些功能的指导和支持。您同样可以使用视觉或基于深度的定位系统,并使用其他传感器进行避障。唯一的要求是您必须按照下面的标准选择实现。
标准
REP 105 <https://www.ros.org/reps/rep-0105.html>
定义了导航和更大的ROS生态系统所需的坐标系和约定。为了利用社区中丰富的定位、里程计和SLAM项目,应始终遵循这些约定。
简而言之,REP-105 规定你至少需要构建一个包含完整 map
-> odom
-> base_link
-> [sensor frames]
的 TF 树来表示你的机器人。TF2 是 ROS 2 中用于表示和获取时间同步转换的时变转换库。全局定位系统(GPS、SLAM、动作捕捉)的任务是至少提供 map
-> odom
转换。然后里程计系统的任务是提供 odom
-> base_link
转换。相对于 base_link
的其余转换应该是静态的,并在你的 URDF 中定义。
全局定位:定位和SLAM
全局定位系统(GPS、SLAM、动作捕捉)的任务是至少提供 map
-> odom
转换。我们提供了 amcl
,它是一种基于粒子滤波器的自适应蒙特卡洛定位技术,用于在静态地图中进行定位。我们还提供 SLAM 工具箱作为默认的 SLAM 算法,用于定位和生成静态地图。
这些方法也可能产生其他输出,包括位置主题、地图或其他元数据,但它们必须提供该转换才能有效。可以使用机器人定位将多个定位方法融合在一起,下面将对此进行讨论。
环境表示
环境表示是机器人感知环境的方式。它还充当各种算法和数据源的中央定位,将它们的信息合并到一个单一空间中。然后,控制器、规划器和恢复模块使用该空间安全高效地计算其任务。
代价地图和层
当前的环境表示是成本地图。成本地图是一个常规的2D单元格网格,其中包含未知、自由、占用或膨胀成本。然后搜索该成本地图以计算全局路径或对其进行采样以计算局部控制力。
各种成本地图层被实现为pluginlib插件,用于将信息缓冲到成本地图中。其中包括来自激光雷达(LIDAR)、雷达(RADAR)、声纳、深度图像等的信息。在将传感器数据输入到成本地图层之前,对其进行处理可能是明智的,但这取决于开发人员。
可以创建成本地图层,使用相机或深度传感器在场景中检测和跟踪障碍物,以进行碰撞避免。此外,可以创建层以根据某些规则或启发式算法更改底层成本地图。最后,它们可以用于将实时数据缓冲到2D或3D世界中以进行二值障碍物标记。
代价地图过滤器
想象一下,您正在为地图文件(或任何图像文件)进行注释,以便根据注释地图中的位置执行特定操作。标记/注释的示例可能是禁区以避免在内部进行规划,或使像素属于标记区域中的最大速度。这个标记的地图被称为"过滤蒙版"。就像覆盖在表面上的蒙版一样,它可以与主地图具有相同的大小、姿态和比例,也可以不同。过滤蒙版的主要目标是提供在地图上标记区域以及一些附加功能或行为变化的能力。
成本地图过滤器是一种基于成本地图层的方法,将空间相关的行为变化(通过过滤器掩码进行注释)应用到Nav2堆栈中。成本地图过滤器被实现为成本地图插件。这些插件被称为"过滤器",因为它们通过在过滤器掩码上标记的空间注释来过滤成本地图。为了创建一个经过滤波的成本地图并在标注区域内改变机器人的行为,过滤器插件会读取来自过滤器掩码的数据。这些数据被线性转换为过滤空间中的特征图。通过这个转换后的特征图以及地图/成本地图、任何传感器数据和当前机器人坐标过滤器,可以更新底层成本地图并根据机器人所处的位置改变机器人的行为。例如,使用成本地图过滤器可以实现以下功能:
机器人永远不会进入的禁止/安全区域。
速度限制区域。进入这些区域的机器人的最大速度将受限制。
机器人在工业环境和仓库中移动的优选路径。
其他形式
还存在其他形式的环境表示。这些包括:
梯度地图,类似于成本地图,但表示表面梯度以检查可通过性
3D成本地图,表示三维空间,但也需要进行三维规划和碰撞检查。
网格地图,类似于梯度地图,但包含多个角度的表面网格
“向量空间”,利用传感器信息并使用机器学习来检测个体物品和位置以进行跟踪,而不是缓冲离散点。