当前位置: 首页 > article >正文

亚博microros小车-原生ubuntu支持系列:19 nav2 导航

开始小车测试之前,先补充下背景知识

nav2

Navigation2具有下列工具:

  • 加载、提供和存储地图的工具(地图服务器Map Server)

  • 在地图上定位机器人的工具 (AMCL)

  • 避开障碍物从A点移动到B点的路径规划工具(Nav2 Planner)

  • 跟随路径过程中控制机器人的工具(Nav2 Controller)

  • 将传感器数据转换为机器人世界中的成本地图表达的工具(Nav2 Costmap 2D)

  • 使用行为树构建复杂机器人行为的工具(Nav2 行为树和BT Navigator)

  • 发生故障时计算恢复行为的工具(Nav2 Recoveries)

  • 跟随顺序航点的工具(Nav2 Waypoint Follower)

  • 管理服务器生命周期的工具和看门狗(Nav2 Lifecycle Manager)

  • 启用用户自定义算法和行为的插件(Nav2 Core)

Navigation 2(Nav 2)是ROS 2中自带的导航框架,其目的是能够通过一种安全的方式使移动机器人从A点移动到B点。所以,Nav 2可以完成动态路径规划、计算电机速度、避开障碍物和恢复结构等行为。

Nav 2使用行为树(BT,Behavior Trees)调用模块化服务器来完成一个动作。动作可以是计算路径、控制工作(control efforts)、恢复或其他与导航相关的动作。这些动作都是通过动作服务器与行为树(BT)进行通信的独立节点。

资料参考网址:

Navigation2 文档:https://navigation.ros.org/index.html

Navigation2 github:https://github.com/ros-planning/navigation2

之前小鱼老师讲的:ros2笔记-7.3机器人导航框架navigation2_ros2 安装nav2-CSDN博客

亚博接下来就是启动launch了。我看了下,觉得还是要补充下对应的bringup跟dwb_nav_params.yaml。

nav2 bringup

  了解下里面有什么脚本,启动了什么节点。

bringup_launch.py

   # Specify the actions
    bringup_cmd_group = GroupAction([
        PushRosNamespace(
            condition=IfCondition(use_namespace),
            namespace=namespace),

        Node(
            condition=IfCondition(use_composition),
            name='nav2_container',
            package='rclcpp_components',
            executable='component_container_isolated',
            parameters=[configured_params, {'autostart': autostart}],
            arguments=['--ros-args', '--log-level', log_level],
            remappings=remappings,
            output='screen'),

        IncludeLaunchDescription(
            PythonLaunchDescriptionSource(os.path.join(launch_dir, 'slam_launch.py')),
            condition=IfCondition(slam),
            launch_arguments={'namespace': namespace,
                              'use_sim_time': use_sim_time,
                              'autostart': autostart,
                              'use_respawn': use_respawn,
                              'params_file': params_file}.items()),

        IncludeLaunchDescription(
            PythonLaunchDescriptionSource(os.path.join(launch_dir,
                                                       'localization_launch.py')),
            condition=IfCondition(PythonExpression(['not ', slam])),
            launch_arguments={'namespace': namespace,
                              'map': map_yaml_file,
                              'use_sim_time': use_sim_time,
                              'autostart': autostart,
                              'params_file': params_file,
                              'use_composition': use_composition,
                              'use_respawn': use_respawn,
                              'container_name': 'nav2_container'}.items()),

        IncludeLaunchDescription(
            PythonLaunchDescriptionSource(os.path.join(launch_dir, 'navigation_launch.py')),
            launch_arguments={'namespace': namespace,
                              'use_sim_time': use_sim_time,
                              'autostart': autostart,
                              'params_file': params_file,
                              'use_composition': use_composition,
                              'use_respawn': use_respawn,
                              'container_name': 'nav2_container'}.items()),
    ])

创建了一个动作群组,里面包含

    命名空间指定:如果use_namespace,指定命名空间为namespace
    节点启动:启动rclcpp_components功能包中的component_container_isolated可执行,并命名为nav2_container节点
        启动参数为configured_params,该参数是从父启动文件传递过来的params_file参数中读取到的
        并将节点中的话题进行重映射
    launch文件启动,启动了3个子launch文件:
        slam_launch.py文件,启动条件为slam参数,默认为false不启动;
        localization_launch.py文件,启动条件为slam参数为false时,即PythonExpression(['not ', slam])默认为true 所以默认启动 localization_launch.py
        navigation_launch.py文件

 slam_launch.py

    slam_launch_file = os.path.join(slam_toolbox_dir, 'launch', 'online_sync_launch.py')
start_map_saver_server_cmd = Node(
            package='nav2_map_server',
            executable='map_saver_server',
            output='screen',
            respawn=use_respawn,
            respawn_delay=2.0,
            arguments=['--ros-args', '--log-level', log_level],
            parameters=[configured_params])

    start_lifecycle_manager_cmd = Node(
            package='nav2_lifecycle_manager',
            executable='lifecycle_manager',
            name='lifecycle_manager_slam',
            output='screen',
            arguments=['--ros-args', '--log-level', log_level],
            parameters=[{'use_sim_time': use_sim_time},
                        {'autostart': autostart},
                        {'node_names': lifecycle_nodes}])

调用了slam_toolbox工程下online_sync_launch.py

map_saver_server,     #启动了地图储存服务节点

import os

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory


def generate_launch_description():
    use_sim_time = LaunchConfiguration('use_sim_time')
    slam_params_file = LaunchConfiguration('slam_params_file')

    declare_use_sim_time_argument = DeclareLaunchArgument(
        'use_sim_time',
        default_value='true',
        description='Use simulation/Gazebo clock')
    declare_slam_params_file_cmd = DeclareLaunchArgument(
        'slam_params_file',
        default_value=os.path.join(get_package_share_directory("slam_toolbox"),
                                   'config', 'mapper_params_online_sync.yaml'),
        description='Full path to the ROS2 parameters file to use for the slam_toolbox node')

    start_sync_slam_toolbox_node = Node(
        parameters=[
          slam_params_file,
          {'use_sim_time': use_sim_time}
        ],
        package='slam_toolbox',
        executable='sync_slam_toolbox_node',
        name='slam_toolbox',
        output='screen')

    ld = LaunchDescription()

    ld.add_action(declare_use_sim_time_argument)
    ld.add_action(declare_slam_params_file_cmd)
    ld.add_action(start_sync_slam_toolbox_node)

    return ld

'sync_slam_toolbox_node',   #启动了slam工具箱同步定位建图

作用:slam同步定位建图,储存地图。

localization_launch.py

  load_nodes = GroupAction(
        condition=IfCondition(PythonExpression(['not ', use_composition])),
        actions=[
            Node(
                package='nav2_map_server',
                executable='map_server',
                name='map_server',
                output='screen',
                respawn=use_respawn,
                respawn_delay=2.0,
                parameters=[configured_params],
                arguments=['--ros-args', '--log-level', log_level],
                remappings=remappings),
            Node(
                package='nav2_amcl',
                executable='amcl',
                name='amcl',
                output='screen',
                respawn=use_respawn,
                respawn_delay=2.0,
                parameters=[configured_params],
                arguments=['--ros-args', '--log-level', log_level],
                remappings=remappings),
            Node(
                package='nav2_lifecycle_manager',
                executable='lifecycle_manager',
                name='lifecycle_manager_localization',
                output='screen',
                arguments=['--ros-args', '--log-level', log_level],
                parameters=[{'use_sim_time': use_sim_time},
                            {'autostart': autostart},
                            {'node_names': lifecycle_nodes}])
        ]
    )

启动了节点

  • nav2_map_server功能包下的map_server节点
  • nav2_amcl功能包下的amcl节点
  • nav2_lifecycle_manager功能包下的lifecycle_manager_localization节点

作用:启动地图服务,在地图上给机器人定位。

navigation_launch.py

load_nodes = GroupAction(
        condition=IfCondition(PythonExpression(['not ', use_composition])),
        actions=[
            Node(
                package='nav2_controller',
                executable='controller_server',
                output='screen',
                respawn=use_respawn,
                respawn_delay=2.0,
                parameters=[configured_params],
                arguments=['--ros-args', '--log-level', log_level],
                remappings=remappings + [('cmd_vel', 'cmd_vel_nav')]),
            Node(
                package='nav2_smoother',
                executable='smoother_server',
                name='smoother_server',
                output='screen',
                respawn=use_respawn,
                respawn_delay=2.0,
                parameters=[configured_params],
                arguments=['--ros-args', '--log-level', log_level],
                remappings=remappings),
            Node(
                package='nav2_planner',
                executable='planner_server',
                name='planner_server',
                output='screen',
                respawn=use_respawn,
                respawn_delay=2.0,
                parameters=[configured_params],
                arguments=['--ros-args', '--log-level', log_level],
                remappings=remappings),
            Node(
                package='nav2_behaviors',
                executable='behavior_server',
                name='behavior_server',
                output='screen',
                respawn=use_respawn,
                respawn_delay=2.0,
                parameters=[configured_params],
                arguments=['--ros-args', '--log-level', log_level],
                remappings=remappings),
            Node(
                package='nav2_bt_navigator',
                executable='bt_navigator',
                name='bt_navigator',
                output='screen',
                respawn=use_respawn,
                respawn_delay=2.0,
                parameters=[configured_params],
                arguments=['--ros-args', '--log-level', log_level],
                remappings=remappings),
            Node(
                package='nav2_waypoint_follower',
                executable='waypoint_follower',
                name='waypoint_follower',
                output='screen',
                respawn=use_respawn,
                respawn_delay=2.0,
                parameters=[configured_params],
                arguments=['--ros-args', '--log-level', log_level],
                remappings=remappings),
            Node(
                package='nav2_velocity_smoother',
                executable='velocity_smoother',
                name='velocity_smoother',
                output='screen',
                respawn=use_respawn,
                respawn_delay=2.0,
                parameters=[configured_params],
                arguments=['--ros-args', '--log-level', log_level],
                remappings=remappings +
                        [('cmd_vel', 'cmd_vel_nav'), ('cmd_vel_smoothed', 'cmd_vel')]),
            Node(
                package='nav2_lifecycle_manager',
                executable='lifecycle_manager',
                name='lifecycle_manager_navigation',
                output='screen',
                arguments=['--ros-args', '--log-level', log_level],
                parameters=[{'use_sim_time': use_sim_time},
                            {'autostart': autostart},
                            {'node_names': lifecycle_nodes}]),
        ]

配置指南 — Navigation 2 1.0.0 文档  推荐看看小鱼老师的nav2文档,下面就是摘自文档的部分内容。参数没贴。

'controller_server',     #启动机器人控制器,Controller Server实现了用于处理堆栈的控制器请求的服务器,并承载了插件实现的映射表。它将接收控制器、进度检查器和目标检查器的路径和插件名称,并调用相应的插件。

‘smoother_server’,由于Planner规划器搜索的路径最优性标准通常与现实情况相比有所降低,因此额外的路径细化通常是有益的。为此目的,引入了平滑器,通常负责减少路径粗糙度和平滑突然旋转,但也负责增加与障碍物和高成本区域的距离,因为平滑器可以访问全局环境表示。

'planner_server',        规划服务器实现了用于处理堆栈的规划请求的服务器,并托管插件实现的地图。它将接收一个目标和要使用的规划插件名称,并调用适当的插件来计算到目标的路径。

‘behavior_server’,Behavior Server实现了处理恢复行为请求和托管实现各种C++行为的插件向量的服务器。也可以为每个自定义行为实现独立的行为服务器,但此服务器允许多个行为共享资源,如costmaps和TF缓冲区,以降低新行为的增量成本。

'bt_navigator', BT导航器(行为树导航器)模块实现了NavigateToPose任务接口。它是一种基于行为树的导航实现,旨在允许导航任务的灵活性,并提供一种简便的方式来指定复杂的机器人行为,包括恢复操作。        

'waypoint_follower',   #启动路点跟随,模块通过使用 NavigateToPose 动作服务器实现了一种按照路径点进行跟随的方法。它会接收一组有序的路径点,并尝试按顺序导航到它们。该模块还提供了一个路径点任务执行插件,可用于在路径点上执行自定义行为,如等待用户指令、拍照或拾取物品。如果某个路径点无法到达,stop_on_failure 参数将决定是继续到下一个点还是停止。

‘velocity_smoother’ 是一个包含生命周期组件节点的软件包,用于平滑Nav2发送给机器人控制器的速度。该软件包的目的是通过平滑加速度/突变运动,从Nav2实现速度、加速度和死区的平滑,以减少机器人电机和硬件控制器的磨损。

‘lifecycle_manager’ 生命周期管理器模块以确定性方式实现了处理堆栈生命周期转换状态的方法。它将接收一组有序节点,逐个将它们转换为配置和激活状态以运行堆栈。然后,它将按相反的顺序将堆栈降低到最终状态。它还将与服务器建立连接,以确保它们仍然运行,并在任何非响应或崩溃的节点时降低所有节点。

作用:启动导航核心节点,行为树 规划器 控制器 恢复器 路点跟随

dwb_nav_params.yaml

amcl:
  ros__parameters:
    use_sim_time: False
    alpha1: 0.2
    alpha2: 0.2
    alpha3: 0.2
    alpha4: 0.2
    alpha5: 0.2
    base_frame_id: "base_footprint"
    beam_skip_distance: 0.5
    beam_skip_error_threshold: 0.9
    beam_skip_threshold: 0.3
    do_beamskip: false
    global_frame_id: "map"
    lambda_short: 0.1
    laser_likelihood_max_dist: 2.0
    laser_max_range: 100.0
    laser_min_range: -1.0
    laser_model_type: "likelihood_field"
    max_beams: 60
    max_particles: 2000
    min_particles: 500
    odom_frame_id: "odom"
    pf_err: 0.05
    pf_z: 0.99
    recovery_alpha_fast: 0.0
    recovery_alpha_slow: 0.0
    resample_interval: 1
    robot_model_type: "nav2_amcl::DifferentialMotionModel"
    save_pose_rate: 0.5
    sigma_hit: 0.2
    tf_broadcast: true
    transform_tolerance: 1.0
    update_min_a: 0.2
    update_min_d: 0.25
    z_hit: 0.5
    z_max: 0.05
    z_rand: 0.5
    z_short: 0.05
    scan_topic: scan

bt_navigator:
  ros__parameters:
    use_sim_time: False
    global_frame: map
    robot_base_frame: base_link
    odom_topic: /odom
    bt_loop_duration: 10
    default_server_timeout: 20
    default_bt_xml_filename: "navigate_to_pose_w_replanning_and_recovery.xml"
    # 'default_nav_through_poses_bt_xml' and 'default_nav_to_pose_bt_xml' are use defaults:
    # nav2_bt_navigator/navigate_to_pose_w_replanning_and_recovery.xml
    # nav2_bt_navigator/navigate_through_poses_w_replanning_and_recovery.xml
    # They can be set here or via a RewrittenYaml remap from a parent launch file to Nav2.
    plugin_lib_names:
      - nav2_compute_path_to_pose_action_bt_node
      - nav2_compute_path_through_poses_action_bt_node
      - nav2_smooth_path_action_bt_node
      - nav2_follow_path_action_bt_node
      - nav2_spin_action_bt_node
      - nav2_wait_action_bt_node
      - nav2_assisted_teleop_action_bt_node
      - nav2_back_up_action_bt_node
      - nav2_drive_on_heading_bt_node
      - nav2_clear_costmap_service_bt_node
      - nav2_is_stuck_condition_bt_node
      - nav2_goal_reached_condition_bt_node
      - nav2_goal_updated_condition_bt_node
      - nav2_globally_updated_goal_condition_bt_node
      - nav2_is_path_valid_condition_bt_node
      - nav2_initial_pose_received_condition_bt_node
      - nav2_reinitialize_global_localization_service_bt_node
      - nav2_rate_controller_bt_node
      - nav2_distance_controller_bt_node
      - nav2_speed_controller_bt_node
      - nav2_truncate_path_action_bt_node
      - nav2_truncate_path_local_action_bt_node
      - nav2_goal_updater_node_bt_node
      - nav2_recovery_node_bt_node
      - nav2_pipeline_sequence_bt_node
      - nav2_round_robin_node_bt_node
      - nav2_transform_available_condition_bt_node
      - nav2_time_expired_condition_bt_node
      - nav2_path_expiring_timer_condition
      - nav2_distance_traveled_condition_bt_node
      - nav2_single_trigger_bt_node
      - nav2_goal_updated_controller_bt_node
      - nav2_is_battery_low_condition_bt_node
      - nav2_navigate_through_poses_action_bt_node
      - nav2_navigate_to_pose_action_bt_node
      - nav2_remove_passed_goals_action_bt_node
      - nav2_planner_selector_bt_node
      - nav2_controller_selector_bt_node
      - nav2_goal_checker_selector_bt_node
      - nav2_controller_cancel_bt_node
      - nav2_path_longer_on_approach_bt_node
      - nav2_wait_cancel_bt_node
      - nav2_spin_cancel_bt_node
      - nav2_back_up_cancel_bt_node
      - nav2_assisted_teleop_cancel_bt_node
      - nav2_drive_on_heading_cancel_bt_node
      - nav2_is_battery_charging_condition_bt_node

bt_navigator_navigate_through_poses_rclcpp_node:
  ros__parameters:
    use_sim_time: False

bt_navigator_navigate_to_pose_rclcpp_node:
  ros__parameters:
    use_sim_time: False

controller_server:
  ros__parameters:
    use_sim_time: False
    controller_frequency: 20.0
    min_x_velocity_threshold: 0.001
    min_y_velocity_threshold: 0.5
    min_theta_velocity_threshold: 0.001
    failure_tolerance: 0.3
    progress_checker_plugin: "progress_checker" 
    goal_checker_plugins: ["general_goal_checker"] 
    controller_plugins: ["FollowPath"]

    # Progress checker parameters
    progress_checker:
      plugin: "nav2_controller::SimpleProgressChecker"
      required_movement_radius: 0.5
      movement_time_allowance: 10.0
    # Goal checker parameters
    #precise_goal_checker:
    #  plugin: "nav2_controller::SimpleGoalChecker"
    #  xy_goal_tolerance: 0.25
    #  yaw_goal_tolerance: 0.25
    #  stateful: True
    general_goal_checker:
      stateful: True
      plugin: "nav2_controller::SimpleGoalChecker"
      xy_goal_tolerance: 0.25
      yaw_goal_tolerance: 0.25
    # DWB parameters
    FollowPath:
      plugin: "dwb_core::DWBLocalPlanner"
      debug_trajectory_details: True
      min_vel_x: -0.20
      min_vel_y: 0.0
      max_vel_x: 0.30
      max_vel_y: 0.0
      max_vel_theta: 1.0
      min_speed_xy: -0.20
      max_speed_xy: 0.30
      min_speed_theta: -0.5
      # Add high threshold velocity for turtlebot 3 issue.
      # https://github.com/ROBOTIS-GIT/turtlebot3_simulations/issues/75
      acc_lim_x: 2.5
      acc_lim_y: 0.0
      acc_lim_theta: 3.2
      decel_lim_x: -2.5
      decel_lim_y: 0.0
      decel_lim_theta: -3.2
      vx_samples: 20
      vy_samples: 5
      vtheta_samples: 20
      sim_time: 1.7
      linear_granularity: 0.05
      angular_granularity: 0.025
      transform_tolerance: 0.2
      xy_goal_tolerance: 0.25
      trans_stopped_velocity: 0.25
      short_circuit_trajectory_evaluation: True
      stateful: True
      critics: ["RotateToGoal", "Oscillation", "BaseObstacle", "GoalAlign", "PathAlign", "PathDist", "GoalDist"]
      BaseObstacle.scale: 0.02
      PathAlign.scale: 32.0
      PathAlign.forward_point_distance: 0.1
      GoalAlign.scale: 24.0
      GoalAlign.forward_point_distance: 0.1
      PathDist.scale: 32.0
      GoalDist.scale: 24.0
      RotateToGoal.scale: 32.0
      RotateToGoal.slowing_factor: 5.0
      RotateToGoal.lookahead_time: -1.0

local_costmap:
  local_costmap:
    ros__parameters:
      update_frequency: 5.0
      publish_frequency: 2.0
      global_frame: odom
      robot_base_frame: base_link
      use_sim_time: False
      rolling_window: true
      width: 3
      height: 3
      resolution: 0.05
      robot_radius: 0.22
      plugins: ["voxel_layer", "inflation_layer"]
      inflation_layer:
        plugin: "nav2_costmap_2d::InflationLayer"
        cost_scaling_factor: 3.0
        inflation_radius: 0.55
      voxel_layer:
        plugin: "nav2_costmap_2d::VoxelLayer"
        enabled: True
        publish_voxel_map: True
        origin_z: 0.0
        z_resolution: 0.05
        z_voxels: 16
        max_obstacle_height: 2.0
        mark_threshold: 0
        observation_sources: scan
        scan:
          topic: /scan
          max_obstacle_height: 2.0
          clearing: True
          marking: True
          data_type: "LaserScan"
          raytrace_max_range: 3.0
          raytrace_min_range: 0.0
          obstacle_max_range: 2.5
          obstacle_min_range: 0.0
      static_layer:
        plugin: "nav2_costmap_2d::StaticLayer"
        map_subscribe_transient_local: True
      always_send_full_costmap: True

global_costmap:
  global_costmap:
    ros__parameters:
      update_frequency: 1.0
      publish_frequency: 1.0
      global_frame: map
      robot_base_frame: base_link
      use_sim_time: False
      robot_radius: 0.22
      resolution: 0.05
      track_unknown_space: true
      plugins: ["static_layer", "obstacle_layer", "inflation_layer"]
      obstacle_layer:
        plugin: "nav2_costmap_2d::ObstacleLayer"
        enabled: True
        observation_sources: scan
        scan:
          topic: /scan
          max_obstacle_height: 2.0
          clearing: True
          marking: True
          data_type: "LaserScan"
          raytrace_max_range: 3.0
          raytrace_min_range: 0.0
          obstacle_max_range: 2.5
          obstacle_min_range: 0.0
      static_layer:
        plugin: "nav2_costmap_2d::StaticLayer"
        map_subscribe_transient_local: True
      inflation_layer:
        plugin: "nav2_costmap_2d::InflationLayer"
        cost_scaling_factor: 3.0
        inflation_radius: 0.55
      always_send_full_costmap: True

map_server:
  ros__parameters:
    use_sim_time: False
    # Overridden in launch by the "map" launch configuration or provided default value.
    # To use in yaml, remove the default "map" value in the tb3_simulation_launch.py file & provide full path to map below.
    yaml_filename: ""

map_saver:
  ros__parameters:
    use_sim_time: False
    save_map_timeout: 5.0
    free_thresh_default: 0.25
    occupied_thresh_default: 0.65
    map_subscribe_transient_local: True

planner_server:
  ros__parameters:
    expected_planner_frequency: 20.0
    use_sim_time: False
    planner_plugins: ["GridBased"]
    GridBased:
      plugin: "nav2_navfn_planner/NavfnPlanner"
      tolerance: 0.5
      use_astar: false
      allow_unknown: true
smoother_server:
  ros__parameters:
    use_sim_time: False
    smoother_plugins: ["simple_smoother"]
    simple_smoother:
      plugin: "nav2_smoother::SimpleSmoother"
      tolerance: 1.0e-10
      max_its: 1000
      do_refinement: False

behavior_server:
  ros__parameters:
    costmap_topic: local_costmap/costmap_raw
    footprint_topic: local_costmap/published_footprint
    cycle_frequency: 10.0
    behavior_plugins: ["spin", "backup", "drive_on_heading", "assisted_teleop", "wait"]
    spin:
      plugin: "nav2_behaviors/Spin"
    backup:
      plugin: "nav2_behaviors/BackUp"
    drive_on_heading:
      plugin: "nav2_behaviors/DriveOnHeading"
    wait:
      plugin: "nav2_behaviors/Wait"
    assisted_teleop:
      plugin: "nav2_behaviors/AssistedTeleop"
    global_frame: odom
    robot_base_frame: base_link
    transform_tolerance: 0.1
    use_sim_time: False
    simulate_ahead_time: 2.0
    max_rotational_vel: 1.0
    min_rotational_vel: 0.4
    rotational_acc_lim: 3.2

robot_state_publisher:
  ros__parameters:
    use_sim_time: False

waypoint_follower:
  ros__parameters:
    use_sim_time: False
    loop_rate: 20
    stop_on_failure: false
    waypoint_task_executor_plugin: "wait_at_waypoint"
    wait_at_waypoint:
      plugin: "nav2_waypoint_follower::WaitAtWaypoint"
      enabled: True
      waypoint_pause_duration: 200

velocity_smoother:
  ros__parameters:
    use_sim_time: False
    smoothing_frequency: 20.0
    scale_velocities: False
    feedback: "OPEN_LOOP"
    max_velocity: [0.26, 0.0, 1.0]
    min_velocity: [-0.26, 0.0, -1.0]
    max_accel: [2.5, 0.0, 3.2]
    max_decel: [-2.5, 0.0, -3.2]
    odom_topic: "odom"
    odom_duration: 0.1
    deadband_velocity: [0.0, 0.0, 0.0]
    velocity_timeout: 1.0

这参数配置文件300多行,的确很多,我也没逐行看。大概有几个主要的:

planner_server节点的参数,用于设置路径规划器(global planner)的参数,如地图、规划器类型、规划时间等。
controller_server节点的参数,用于设置控制器(local planner)的参数,如速度、加速度、PID参数等。
recoveries_server节点的参数,用于设置恢复行为(recovery behaviors)的参数,如障碍物避让、路径重新规划等。
bt_navigator节点的参数,用于设置行为树(behavior tree)导航器的参数,如行为树的文件路径、调试模式等。
通过修改nav2_params.yaml文件中的这些参数,可以调整导航栈的行为,以适应不同的场景和需求

小鱼老师nav2 文档上有:生命周期管理器 — Navigation 2 1.0.0 文档

也有大佬的文章汇总了参数,并做了进一步说明,限于篇幅,推荐看原文,不贴了:

【10天速通Navigation2】(六):Navigation2 导航bringup基础配置和参数详解_十天速通-CSDN博客

测试

启动小车代理

sudo docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:humble udp4 --port 8090 -v4
首先启动小车处理底层数据程序
ros2 launch yahboomcar_bringup yahboomcar_bringup_launch.py      
bohu@bohu-TM1701:~/yahboomcar/yahboomcar_ws$ ros2 launch yahboomcar_bringup yahboomcar_bringup_launch.py
[INFO] [launch]: All log files can be found below /home/bohu/.ros/log/2025-02-02-14-52-51-635219-bohu-TM1701-485615
[INFO] [launch]: Default logging verbosity is set to INFO
---------------------robot_type = x3---------------------
[INFO] [complementary_filter_node-1]: process started with pid [485617]
[INFO] [ekf_node-2]: process started with pid [485619]
[INFO] [static_transform_publisher-3]: process started with pid [485621]
[INFO] [joint_state_publisher-4]: process started with pid [485623]
[INFO] [robot_state_publisher-5]: process started with pid [485625]
[INFO] [static_transform_publisher-6]: process started with pid [485627]
[static_transform_publisher-3] [WARN] [1738479171.990437080] []: Old-style arguments are deprecated; see --help for new-style arguments
[static_transform_publisher-6] [WARN] [1738479171.991202044] []: Old-style arguments are deprecated; see --help for new-style arguments
[static_transform_publisher-3] [INFO] [1738479172.104536837] [base_link_to_base_imu]: Spinning until stopped - publishing transform
[static_transform_publisher-3] translation: ('-0.002999', '-0.003000', '0.031701')
[static_transform_publisher-3] rotation: ('0.000000', '0.000000', '0.000000', '1.000000')
[static_transform_publisher-3] from 'base_link' to 'imu_frame'
[complementary_filter_node-1] [INFO] [1738479172.137987218] [complementary_filter_gain_node]: Starting ComplementaryFilterROS
[static_transform_publisher-6] [INFO] [1738479172.155545031] [static_transform_publisher_HOLxXJ1FIA5414tp]: Spinning until stopped - publishing transform
[static_transform_publisher-6] translation: ('0.000000', '0.000000', '0.050000')
[static_transform_publisher-6] rotation: ('0.000000', '0.000000', '0.000000', '1.000000')
[static_transform_publisher-6] from 'base_footprint' to 'base_link'
[robot_state_publisher-5] [WARN] [1738479172.216038947] [kdl_parser]: The root link base_link has an inertia specified in the URDF, but KDL does not support a root link with an inertia.  As a workaround, you can add an extra dummy link to your URDF.
[robot_state_publisher-5] [INFO] [1738479172.216185449] [robot_state_publisher]: got segment base_link
[robot_state_publisher-5] [INFO] [1738479172.216257807] [robot_state_publisher]: got segment imu_Link
[robot_state_publisher-5] [INFO] [1738479172.216278937] [robot_state_publisher]: got segment jq1_Link
[robot_state_publisher-5] [INFO] [1738479172.216289860] [robot_state_publisher]: got segment jq2_Link
[robot_state_publisher-5] [INFO] [1738479172.216301021] [robot_state_publisher]: got segment radar_Link
[robot_state_publisher-5] [INFO] [1738479172.216315380] [robot_state_publisher]: got segment yh_Link
[robot_state_publisher-5] [INFO] [1738479172.216328033] [robot_state_publisher]: got segment yq_Link
[robot_state_publisher-5] [INFO] [1738479172.216339831] [robot_state_publisher]: got segment zh_Link
[robot_state_publisher-5] [INFO] [1738479172.216355571] [robot_state_publisher]: got segment zq_Link
[joint_state_publisher-4] [INFO] [1738479173.196961127] [joint_state_publisher]: Waiting for robot_description to be published on the robot_description topic...

启动rviz,可视化导航,终端输入

 ros2 launch yahboomcar_nav display_launch.py #rviz可视化

此时还没有显示地图加载,因为还没有启动导航的程序,所以没有地图加载。接下来运行导航节点,

ros2 launch  yahboomcar_nav navigation_dwb_launch.py maps:=/home/bohu/maps-data/gmapping/yahboom_map.yaml

此时可以看到地图加载进去了,然后我们点击【2D Pose Estimate】,给小车设置初始位姿,根据小车在实际环境中的位置,在rviz中用鼠标点击拖动,小车模型移动我们设置的位置。

单点导航,点击【2D Goal Pose】工具,然后在rviz中选择一个目标点,小车结合周围的情况,规划出一条路径并且沿着路径移动到目标点。

多点导航,没有截图。用了nav2插件

节点通信图

原图太大,截图了小部分太复杂了。

tf TREE

navigation_dwb_launch.py

import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node

def generate_launch_description():
    package_path = get_package_share_directory('yahboomcar_nav')
    nav2_bringup_dir = get_package_share_directory('nav2_bringup')

    use_sim_time = LaunchConfiguration('use_sim_time', default='false')
    namespece = LaunchConfiguration('namespece', default='')
    map_yaml_path = LaunchConfiguration(
        'maps', default=os.path.join('/home/yahboom/yahboomcar_ws/src/yahboomcar_nav', 'maps', 'yahboom_map.yaml')) 
    nav2_param_path = LaunchConfiguration('params_file', default=os.path.join(
        package_path, 'params', 'dwb_nav_params.yaml'))

    return LaunchDescription([
        DeclareLaunchArgument('use_sim_time', default_value=use_sim_time,
                              description='Use simulation (Gazebo) clock if true'),
        DeclareLaunchArgument('namespece', default_value=namespece,
                              description='Use simulation (Gazebo) clock if true'),
        DeclareLaunchArgument('maps', default_value=map_yaml_path,
                              description='Full path to map file to load'),
        DeclareLaunchArgument('params_file', default_value=nav2_param_path,
                              description='Full path to param file to load'),

        IncludeLaunchDescription(
            PythonLaunchDescriptionSource(
                [nav2_bringup_dir, '/launch', '/bringup_launch.py']),
            launch_arguments={
                'map': map_yaml_path,
                'use_sim_time': use_sim_time,
                'namespece': namespece,
                'params_file': nav2_param_path}.items(),
        ),
        Node(
            package='yahboomcar_nav',
            executable='stop_car'
        ) ,
        Node(
     package='tf2_ros',
     executable='static_transform_publisher',
     name='base_link_to_base_laser',
     arguments=['-0.0046412', '0' , '0.094079','0','0','0','base_link','laser_frame']
    )
    ])

这里启动了以下几个节点:

  • base_link_to_base_laser:发布静态的TF变换;

  • stop_car:停车节点,ctrl c退出程序后,会发布停车速度给到小车;

  • bringup_launch.py:启动导航的launch文件,文件位于,/opt/ros/humble/share/nav2_bringup/launch

另外还加载了一个导航参数配置文件dwb_nav_params.yaml和加载地图文件yahboom_map.yaml,

参见上面的第一部分代码。

测试发现的问题:

小车运行前面没啥问题,能规划路线去指定点。跑了几圈之后,误差有积累,此时位置、姿态不太准确。会显示自己在障碍物边上停止运动,实际上没有。此类问题不知道怎么解决。


http://www.kler.cn/a/529994.html

相关文章:

  • elasticsearch8.15 高可用集群搭建(含认证Kibana)
  • Jenkins未在第一次登录后设置用户名,第二次登录不进去怎么办?
  • PhotoShop中JSX编辑器安装
  • C++并发编程指南08
  • 【ArcGIS遇上Python】批量提取多波段影像至单个波段
  • 【etcd】二进制安装etcd
  • priority_queue
  • Kanass快速安装配置教程(入门级)
  • RK3568 wifi使用(使用Linux指令操作)
  • 每日一题——用两个栈实现队列
  • 一分钟深挖@Value注解和@ConfigurationProperities注解的区别
  • 基于SpringBoot的智慧康老疗养院管理系统的设计与实现(源码+SQL脚本+LW+部署讲解等)
  • Spring Boot Web项目全解析:Thymeleaf语法
  • 『 C 』 `##` 在 C 语言宏定义中的作用解析
  • 2.[网鼎杯 2020 朱雀组]phpweb
  • Android 开发:新的一年,新的征程
  • 【5. C++ 变量作用域及其深入探讨】
  • 2 [GitHub遭遇严重供应链投毒攻击]
  • 城市道路车辆自行车摩托车公交车检测数据集VOC+YOLO格式5236张5类别
  • FlashAttention v1 论文解读
  • Word List 2
  • 二叉树——102,107,199,637
  • 云原生(五十三) | SQL查询操作
  • 机器学习--概览
  • 使用等宽等频法进行数据特征离散化
  • C++, STL容器 list:双向链表深度解析