260520

我们接下来继续编写 src/kibot_one_sim/config/nav2_params.yaml 这个文件。

首先是 bt_navigator:

bt_navigator:
  ros__parameters:
    global_frame: map
    robot_base_frame: base_link
    odom_topic: /odom

接下来告诉我们的 bt_navigator 需要启动哪些导航器(navigator):

bt_navigator:
  ros__parameters:
    global_frame: map
    robot_base_frame: base_link
    odom_topic: /odom
    navigators: ["navigate_to_pose", "navigate_through_poses"]
    navigate_to_pose:
      plugin: "nav2_bt_navigator::NavigateToPoseNavigator"
    navigate_through_poses:
      plugin: "nav2_bt_navigator::NavigateThroughPosesNavigator"

这里我们启用了 navigate_to_pose 和 navigate_through_poses 这两个导航器。

最后加上错误码:

bt_navigator:
  ros__parameters:
    error_code_names:
      - compute_path_error_code
      - follow_path_error_code

在这里写两个错误码的作用是,当 bt_navigator 行为树执行失败的时候,错误码向上传递是白名单制的,只会从指定的 blackboard key 中来提取错误码,避免底层将所有错误码都一起传过来,影响我们判断。

然后我们接下来编写一下 controller_server,该节点负责将我们规划的路径转为实际的速度。

controller_server:
  ros__parameters:
    controller_frequency: 20.0
    controller_plugins: ["FollowPath"]

这里的 controller_frequency 我们设置为 20,即表示每秒计算 20 次速度,保证足够平滑。

具体的控制器插件实例,我们通过controller_plugins 设置为 FollowPath。

接下来加入进度检查:

controller_server:
  ros__parameters:
    progress_checker_plugins: ["progress_checker"]
    progress_checker:
      plugin: "nav2_controller::SimpleProgressChecker"
      required_movement_radius: 0.5
      movement_time_allowance: 10.0

我们这里定义来什么叫“没有进展”:

  1. required_movement_radius: 0.5,表示机器人需要移动至少 0.5m。
  2. movement_time_allowance: 10.0,表示如果机器人十秒内没有达到这个移动量,就会触发进展失败判定,可能会认为机器人失败了。

在实际表现中,如果因此失败了,他可能会返回 105 状态码,具体内容为:FAILED_TO_MAKE_PROGRESS。

接下来我们再加入 goal_checker:

controller_server:
  ros__parameters:
    general_goal_checker:
      stateful: True
      plugin: "nav2_controller::SimpleGoalChecker"
      xy_goal_tolerance: 0.10
      yaw_goal_tolerance: 0.25

这里我们定义了什么叫成功:

  1. 平面距离误差小于 0.10m
  2. 朝向误差小于 0.25rad,差不多是 14.3 度。

这里还有一个参数就是 stateful,表示对于到达目标的判断是否“带有记忆”。

即,在打开开关后,检查逻辑可能是这样的:

  1. 机器人先进入目标的 0.1m 范围内
  2. 一旦进入到了这个范围,就标记为 位置已达标
  3. 然后机器人剩下就只需要调整自己的角度就可以了

这么做的好处是,我们的小车到达了目标点附近后,就只需要原地转圈就可以了,而转圈过程机器人由于随机的抖动可能会离开平面误差允许的范围内,如果每一帧都重新严格检查平面误差距离的话,就可能会出现刚到达,然后又提示判定没到达的问题。