Ros2
Ros2是Nav2的核心中间件,不熟悉Ros2可以先看Ros2的官方文档
Action Server
就像在ROS中一样,action server是控制像导航等长期运行任务的常用方式。
Action servers和规范化的service十分相似。一个客户端会请求一个一些任务去完成,除非此任务需要很长时间,例如:移动推土机铲子向上推动或者向右形式十米。
在这种情况下,action server和client允许我们调用另一个进程或线程来运行长时间的任务,并为其结果返回一个future,他可以阻塞到action完成为止,但是往往我们只是期望偶尔去检查一下action是否完成并且继续完成在客户端的工作。由于它是长期运行的,因为action server是长时间运行的,所以它还会向其客户端提供反馈。这个反馈定义在.action
,包括请求和相应的类型,它可以是任何东西。在推土机的例子中,一个请求可能是要移动的角度,反馈可能是还要移动的角度,一个结果是移动到此角度 是否成功的布尔值。在导航的例子中,一个请求可能是一个位置,
通过向action client注册回调,可以同步地收集反馈和结果。还可以通过异步地从共享的future对象中请求信息来收集它们。两者都需要spinning客户端节点来处理回调。
Action servers在使用此stack(堆栈?)和最高级别的BT导航器通信,通过NavigateToPose
action 消息。它们还用于BT导航器与后续较小的action server通信,以计算计划、控制工作和恢复。每个action servers
都将在nav2_msgs中有自己的唯一.action
类型,用于与服务器交互。
生命周期节点和Bond
在ROS2中,生命周期(管理)节点是唯一的。它们是包含启动和关闭ROS 2服务器的状态机转换的节点,这有助于确定ROS系统在启动和关闭时的行为
当一个节点被启动的时候,他是一个没有被配置的状态,仅仅是处理node的一个构造函数,并没有包含任何的ROS的网络启动或者参数读取。在launch系统中或者是supplied lifecycle manager中,节点需要通过配置将其转换为非激活状态,之后,可以通过激活阶段的过渡来激活节点。
在为配置状态下,节点会处理一些信息并且完全准备好运行,在配置阶段(configuration stage),触发on_configure()
方法,会配置所有的参数,ROS网络接口,以及用于安全系统,所有动态分配的内存。在激活阶段(activation stage),触发on_activate()
方法,会激活ROS网络接口,并在程序中设置任何状态以开始处理信息。
在shutdown后,我们把状态转换为停用(deactivating),清理( cleaning up), 关闭(shutting down) 和结束(end)。网络接口分别停用并停止处理,在这些阶段中停用(deactivated and stop processing),释放内存(deallocate memory),退出(exit)。
生命周期节点框架在此项目中应用广泛。
在Nav2中,我们使用了生命周期节点的一个wrapper,nav2_util LifecycleNode
. 此wrapper包装了很多典型的应用,他还为了生命周期管理器(manager)包括了一个bond
链接,以确保在server转换后,它也保持活动状态。如果server崩溃,它会让生命周期管理器知道并向下转换系统,以防止出现重大故障
行为树
行为树(BT)在复杂的机器人任务中变得越来越普遍,这是一系列待完成的树结构任务。它为定义多步骤或多状态应用程序创建了更具可扩展性和易于理解的框架。这与有限状态机(FSM)相反,后者可能具有数十个状态或成百上千个转换。一个例子是足球比赛机器人,将足球比赛的逻辑嵌入到FSM中将具有挑战性并且容易出错,并且存在许多可能的状态和规则。此外,模型动作(例如从左,右或中心射击)的选择尤其不清楚。使用BT,可以创建诸如“踢”,“走”,“向球方向前进”之类的基本语句,并将其重用于许多行为。可以参考此书的前三节
对于此项目,我们将使用BehaviorTree CPP V3库。我们在BT Navigator
内部创建可以构建行为树的节点插件。将节点插件加载到BT中,并在解析树的XML文件时,将关联已注册的名称。至此,我们可以遍历行为树进行导航。
使用这个库的一个原因是它能够加载子树。这意味着Nav2的行为树可以被加载到另一个更高级别的BT中来使用这个项目作为节点插件。一个例子是在足球比赛中,使用Nav2行为树作为“向球方向前进”节点,球检测作为更大任务的一部分。另外,我们为BT提供了一个NavigateToPoseAction插件,这样就可以从客户端应用程序通过通常的操作界面调用Nav2堆栈。
Navigation Servers
Planners和controllers是导航任务的核心。Recoveries用于将机器人脱离糟糕的情况或试图处理各种形式的问题。下面介绍他们一般的概念和使用
Planner, Controller和Recovery Servers
上面三个玩意儿在此项目中就是三个action servers。这些action servers用于承载算法插件的映射,以完成各种任务,它们还承载算法插件用来计算输出的环境表示。
planner和controller会在运行时会配置好和算法相对应的name和类型,这些类型是pluginlib的名字或者是任务的名字。一个例子是名称为FollwePath
的DWB控制器,则所有DWB下的参数都需要放入此命名空间FollowPath.<param>
。
这两个servers会向外暴露和任务相关的action 接口。当行为树标记相应的BT节点时,它将调用action server来处理它的任务,action的回调会选择和他名字一样的算法,即FollowPath
。这使用户可以将行为树中使用的算法抽象为算法类别。例如,你可以使用N个插件控制器来跟踪路径,与充电器对接,避免动态障碍,或使用工具界面,将所有这些插件放在同一个服务器中,允许用户使用单个环境(environmental representation)表示对象,而复制这个对象的成本很高。
每一个Recovery Server,都有他自己的名字,每一个插件也会暴露他们自己的action server。恢复机制还包含了一个costmap的订阅到本地costmap,从controller 接收实时更新了来计算任务。这样可以避免在本地的costmap产生有多个实例,这样的计算成本太高
Planner
Planner的任务是计算出一些目标函数的路径。两个经典的例子:计算一条到目标点的路径或者计算全覆盖路径(规划一条路径可以覆盖所有的空闲空间)。planner可以获得全局环境表示和传感器数据缓存,Planner可以用于
计算最短路径
计算全覆盖路径
沿着稀疏或预定义的路径计算路径
在Nav2中planner的一般任务是计算一条有效的,最优的路径。并且,很多类已经存在并且支持了planner
Controllers
在ROS1中也被称为局部planner,通过它我们可以跟随全局计算的路径或者完成一个局部的任务,控制器将能够访问本地环境表示。许多控制器将机器人向前投射到空间中,并在每次更新迭代中计算局部可行路径,Controller可以
遵循一个路径
在里程表框架内使用探测器与充电站对接
Borad an elevator
- 使用工具接口
Nav2中控制器的一般任务是计算有效的控制量,以遵循全局计划。但是,存在许多类的控制器和本地计划程序。该项目的目标是,所有控制器算法都可以作为此服务器中的插件,用于常见的研究和工业任务。
Recoveries
Recoveries是容错系统的支柱。Recoveries的目标是处理系统的未知或故障情况并自主处理它们。
WayPoint Following
航路点跟踪(Waypoint following)是导航系统的基本功能。它告诉我们的系统如何使用导航到达多个目的地。
State Estimation
在导航的过程中,有两个主要的变换必须提供,即map
到odom
的变换(定位,建图,SLAM)和由里程计系统发布的由odom
到base_link
变换
Standards
简而言之,REP-105声明你至少要为你的机器人构建一个包含完整map-> odom -> base_link ->[sensor frames]的TF树。TF2是我们用来表示和获得时间同步转换的ROS 2中的时变转换库。全局定位系统(GPS, SLAM, Motion Capture)至少需要提供map->odom变换。里程计系统的作用就是提供odom -> base_link转换。相对于base_link的其余转换应该是静态的,并在URDF中定义。
全局位置:定位和SLAM
全局定位系统(GPS, SLAM, Motion Capture)至少需要提供map->odom变换。我们使用使用基于粒子滤波算法的AMCL
来实时定位静态地图,同时,我们也提供了SLAM工具箱来定位和生成静态地图
这些方法还可能产生其他输出,包括位置主题、映射或其他元数据,但它们必须提供有效的转换。多种定位方法可以通过机器人定位融合在一起,下面将进一步讨论。
Odometry
里程计系统的作用就是提供odom -> base_link转换。里程计信息可以从很多地方过来包括激光雷达、雷达、车轮编码器、VIO和imu。该odometry目标是基于机器人运动提供一个平滑、连续的局部坐标系。全局定位系统将更新相对于全局坐标系的转换,以考虑里程漂移。
机器人定位通常用于这种融合。它将采用N个不同类型的传感器,并为TF和一个主题提供连续和平滑的里程表。一个典型的移动机器人装置可能有来自车轮编码器、imu和视觉融合的里程表。
平滑的输出可以用来进行精确的运动推算,并在全局位置更新之间精确地更新机器人的位置。
Environmental Representation
环境表示是机器人感知环境的方式,它还作为各种算法和数据源的中心定位,将它们的信息合并到一个空间中。然后,controllers, planners, 和recoveries利用这个空间安全地、有效地计算他们的任务。
Costmaps and Layers
目前感知环境的方式是costmap。Costmap是包含未知、免费、已占用或膨胀成本的常规2D网格单元。然后搜索这个costmap以计算全局计划或抽样计算本地控制工作。286/5000
各种costmap层被实现为pluginlib插件,以将信息缓冲到costmap中。这包括来自激光雷达、雷达、声纳、深度、图像等的信息。在将传感器数据输入到成本图层之前处理它,但这取决于开发人员。
可以使用摄像机或深度传感器创建Costmap层来检测和跟踪场景中的障碍物以避免碰撞。此外,可以创建层,以基于某些规则或启发式方法在算法上更改底层costmap。最后,它们可以用于将实时数据缓冲到2D或3D世界中,用于二进制障碍标记。
Costmap过滤器
想象一下,您正在注释一个地图文件(或任何图像文件),以便根据已注释的地图中的位置发生特定的操作。标记/注释的示例为把区域排除在外,避免在室内规划路径,这个带注释的映射称为“filter mask”。他的主要目的是提供在地图上标记带有一些附加特性或行为变化的区域的能力。
Costmap filters - 是一种基于成本图层的方法,将filter mask中标注的与空间相关的行为变化应用到Nav2堆栈中。Costmap过滤器被实现为Costmap插件。这些插件被称为“过滤器”,因为它们通过标记在过滤器掩码上的空间注释来过滤成本图。为了制作过滤后的costmap,改变机器人在标注区域的行为,filter plugin读取来自filter mask的数据。这些数据在过滤空间中被线性转换为特征映射。有了这个转换后的特征图和地图/成本图,任何传感器数据和当前机器人坐标过滤器都可以更新底层成本图,并根据机器人所在的位置改变机器人的行为。例如,使用costmap过滤器可以实现以下功能:
机器人永远不会进入的隔离区/安全区。
速度限制的区域。机器人进入这些区域的最大速度将受到限制。
工业环境和仓库中移动机器人的首选车道。
其他形式
还有其他可以表示环境表示的方式存在
- 梯度地图:
- 3D costmaps:用3D表示空间,但也需要3D规划和碰撞检查
- 网格地图:类似于梯度地图,但在许多角度上有表面网格
- 向量空间:吸收传感器信息,并使用机器学习来检测单个项目和位置,以跟踪而不是缓冲离散点。