navigation2 仿真(mppi controller)

写在前面的话

我仿真实验用的车子底盘是阿克曼四轮驱动(前轮转向),试验过程中发现使用 DWB 控制器 无法进行转弯(按下图),而且很容易提前停止,然后想尝试 TEB 控制器,发现 navigation2 已经不支持(teb_controller 不适用 ros2 的问题),说是已经整合到 MPPI 控制器 了,所以有了这篇文章的尝试。

项目 Value
系统 Ubuntu 22.04.5 LTS
ros2版本 humble
建图方案 cartgrapher
底盘驱动 libgazebo_ros_ackermann_drive.so

在这里插入图片描述
图片来源:Navigation2 导航插件

视频演示(B站)

navigation2 仿真(mppi controller) G果-CSDN

遇到的问题

1. Failed to change state for node: behavior_server

终端报错输出(截取)

[component_container_isolated-1] [INFO] [1735056622.655721574] [lifecycle_manager_navigation]: Configuring behavior_server
[component_container_isolated-1] [INFO] [1735056622.655966294] [behavior_server]: Configuring
[component_container_isolated-1] [INFO] [1735056622.660589934] [behavior_server]: Creating behavior plugin spin of type nav2_behaviors::Spin
[component_container_isolated-1] [FATAL] [1735056622.660723154] [behavior_server]: Failed to create behavior spin of type nav2_behaviors::Spin. Exception: According to the loaded plugin descriptions the class nav2_behaviors::Spin with base class type nav2_core::Behavior does not exist. Declared types are  nav2_behaviors/AssistedTeleop nav2_behaviors/BackUp nav2_behaviors/DriveOnHeading nav2_behaviors/Spin nav2_behaviors/Wait
[component_container_isolated-1] [ERROR] [1735056622.661070784] [lifecycle_manager_navigation]: Failed to change state for node: behavior_server
[component_container_isolated-1] [ERROR] [1735056622.661094527] [lifecycle_manager_navigation]: Failed to bring up all requested nodes. Aborting bringup.

nav2_params_mppi.yaml ( behavior_server )

在这里插入图片描述

解决方法

nav2_params_mppi.yaml 中找到 behavior_server 需要把 :: 改成 / 即可

behavior_server:
  ros__parameters:
    local_costmap_topic: local_costmap/costmap_raw
    global_costmap_topic: global_costmap/costmap_raw
    local_footprint_topic: local_costmap/published_footprint
    global_footprint_topic: global_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"
    local_frame: odom_demo
    global_frame: odom_demo #map
    robot_base_frame: base_link
    transform_tolerance: 0.1
    simulate_ahead_time: 2.0
    max_rotational_vel: 1.0
    min_rotational_vel: 0.4
    rotational_acc_lim: 3.2

2. 地图无法加载显示

我已经在 launch 文件中声明了调用地图,但是启动的 rviz2 上无法显示

在这里插入图片描述

报错输出和截图( 终端 和 rviz2 )

[component container isolated-1] [INFO] [1735106301.162350688] [local costmap.local costmap]: Timed out waiting for transform from base_footprint to map to become available, tf error: Invalid frame ID "map" passed to canTransform argument target_frame -frame does not exit

在这里插入图片描述

解决方法

在 nav2_param_mppi.yaml 加上下面这段代码即可

# The yaml_filename does not need to be specified since it going to be set by defaults in launch.
# If you'd rather set it in the yaml, remove the default "map" value in the tb3_simulation_launch.py
# file & provide full path to map below. If CLI map configuration or launch default is provided, that will be used.
map_server:
  ros__parameters:
    yaml_filename: ""

nav2_param_mppi.yaml ( map_server )

在这里插入图片描述

3. 规划路径后车子无法运动

在 navigation2 中控制插件 ControllerServer 发布的速度话题默认是 /cmd_vel,需要进行 remapping,可以在 nav2_bringup 文件夹的 nvigation_launch.py 中找到进行修改;
之前安装 navigation2 是通过sudo apt install ros-humble-navigation2 进行安装,已经经过编译,只读无法修改;
因此,我们把 nav2_bringup 从官网中单独下载修改名称后重新本地编译,从而进行修改使用.

解决方法

  1. 下载 navigation2/tree/humble/nav2_bringup
  2. 改名 nav2_bringup >> nav2_bringup_xu (最好使用 vscode 软件之类的进行全局搜索修改替换)
  3. 找到 nvigation_launch.py 文件进行修改,将 /cmd_vel remapping 为 /car_nav2/cmd_demo(如下图所示)
  4. 在启动导航的launch文件(本文是car_nav2.launch.py)中添加 nav2_bringup_xu 并启动
  5. 重新编译 colcon build

navigation_launch.py

在这里插入图片描述

car_nav2.launch.py
在这里插入图片描述

4. global_costmap 正常 local_costmap 无法显示

运行的时候发现 /map 正常 /local_costmap/costmap 话题都正常,但是在 rviz2 上无法显示,因为导航默认 rviz2 中 Fixed Frame 为 map,导致 local_costmap 无法与 map 建立联系.

解决方法

把 local_costmap 的 global_frame 修改成 map 即可

在这里插入图片描述

大致工程目录结构 car_nav2

├── car_nav2
│ ├── config
│ │ ├── car_leishen_lidar_c16.lua
│ │ ├── car_rplidar.lua
│ │ ├── car_urdf_controllers.yaml
│ │ ├── nav2_params_dwb.yaml
│ │ └── nav2_params_mppi.yaml
│ ├── launch
│ │ ├── car_cartographer.launch.py
│ │ ├── car_gazebo.launch.py
│ │ ├── car_gmapping.launch.py
│ │ ├── car_leishen_c16_cartographer.launch.py
│ │ ├── car_leishen_c16_gmapping.launch.py
│ │ ├── car_nav2.launch.py
│ │ ├── occupancy_grid.launch.py
│ │ ├── robot_state_publisher.launch.py
│ │ └── spawn_car.launch.py
│ ├── maps
│ │ ├── my_map.pgm
│ │ └── my_map.yaml
│ ├── meshes
│ │ ├── base_link.STL
│ │ ├── left_back_orient_Link.STL
│ │ ├── left_back_wheel_Link.STL
│ │ ├── left_front_orient_Link.STL
│ │ ├── left_front_wheel_Link.STL
│ │ ├── right_back_orient_Link.STL
│ │ ├── right_back_wheel_Link.STL
│ │ ├── right_front_orient_Link.STL
│ │ └── right_front_wheel_Link.STL
│ ├── my_map
│ │ ├── test_map.pgm
│ │ └── test_map.yaml
│ ├── nav2_car
│ │ └── init.py
│ ├── package.xml
│ ├── param
│ │ ├── burger.yaml
│ │ ├── car_urdf.yaml
│ │ ├── waffle_pi.yaml
│ │ └── waffle.yaml
│ ├── resource
│ │ └── car_nav2
│ ├── rviz
│ │ ├── car_cartographer.rviz
│ │ ├── lslidar_c16_cartographer.rviz
│ │ ├── nav2_default_view.rviz
│ │ └── nav2_namespaced_view.rviz
│ ├── setup.cfg
│ ├── setup.py
│ ├── test
│ │ ├── test_copyright.py
│ │ ├── test_flake8.py
│ │ └── test_pep257.py
│ ├── urdf
│ │ ├── car_urdf_gazebo.urdf.xacro
│ │ ├── car_urdf.urdf
│ │ ├── car_urdf.urdf.xacro
│ │ └── sensors
│ │ ├── camera_gazebo.xacro
│ │ ├── kinect_gazebo.xacro
│ │ ├── lidar_gazebo.xacro
│ │ └── rgbd_gazebo.xacro
│ └── worlds
│ └── my_world.world

完整的文件 nav2_params_mppi.yaml

amcl:
  ros__parameters:
    use_sim_time: True
    alpha1: 0.2
    alpha2: 0.2
    alpha3: 0.2
    alpha4: 0.2
    alpha5: 0.2
    base_frame_id: "base_link" ###
    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: 200.0 ###
    laser_min_range: -200.0
    laser_model_type: "likelihood_field"
    max_beams: 60
    max_particles: 4000 #2000
    min_particles: 1000 #500
    odom_frame_id: "odom_demo"
    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: 5.0 #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: True
    global_frame: map
    robot_base_frame: base_footprint ###
    odom_topic: /car_nav2/odom_demo
    bt_loop_duration: 10
    default_server_timeout: 20
    wait_for_service_timeout: 1000
    action_server_result_timeout: 900.0
    navigators: ["navigate_to_pose", "navigate_through_poses"]
    navigate_to_pose:
      plugin: "nav2_bt_navigator::NavigateToPoseNavigator"
    navigate_through_poses:
      plugin: "nav2_bt_navigator::NavigateThroughPosesNavigator"
    # '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 is used to add custom BT plugins to the executor (vector of strings).
    # Built-in plugins are added automatically
    # plugin_lib_names: []

    error_code_names:
      - compute_path_error_code
      - follow_path_error_code

controller_server:
  ros__parameters:
    controller_frequency: 20.0
    costmap_update_timeout: 0.30
    min_x_velocity_threshold: 0.001
    min_y_velocity_threshold: 0.5
    min_theta_velocity_threshold: 0.001
    failure_tolerance: 0.3
    progress_checker_plugins: ["progress_checker"]
    goal_checker_plugins: ["general_goal_checker"] # "precise_goal_checker"
    controller_plugins: ["FollowPath"]
    use_realtime_priority: false

    # 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
    FollowPath:
      plugin: "nav2_mppi_controller::MPPIController"
      time_steps: 56
      model_dt: 0.05
      batch_size: 2000
      ax_max: 3.0
      ax_min: -3.0
      ay_max: 3.0
      az_max: 3.5
      vx_std: 0.2
      vy_std: 0.2
      wz_std: 0.4
      vx_max: 0.5
      vx_min: -0.35
      vy_max: 0.5
      wz_max: 1.9
      iteration_count: 1
      prune_distance: 1.7
      transform_tolerance: 0.1
      temperature: 0.3
      gamma: 0.015
      motion_model: "DiffDrive"
      visualize: true
      regenerate_noises: true
      TrajectoryVisualizer:
        trajectory_step: 5
        time_step: 3
      AckermannConstraints:
        min_turning_r: 0.2
      critics: [
        "ConstraintCritic", "CostCritic", "GoalCritic",
        "GoalAngleCritic", "PathAlignCritic", "PathFollowCritic",
        "PathAngleCritic", "PreferForwardCritic"]
      ConstraintCritic:
        enabled: true
        cost_power: 1
        cost_weight: 4.0
      GoalCritic:
        enabled: true
        cost_power: 1
        cost_weight: 5.0
        threshold_to_consider: 1.4
      GoalAngleCritic:
        enabled: true
        cost_power: 1
        cost_weight: 3.0
        threshold_to_consider: 0.5
      PreferForwardCritic:
        enabled: true
        cost_power: 1
        cost_weight: 5.0
        threshold_to_consider: 0.5
      CostCritic:
        enabled: true
        cost_power: 1
        cost_weight: 3.81
        critical_cost: 300.0
        consider_footprint: true
        collision_cost: 1000000.0
        near_goal_distance: 1.0
        trajectory_point_step: 2
      PathAlignCritic:
        enabled: true
        cost_power: 1
        cost_weight: 14.0
        max_path_occupancy_ratio: 0.05
        trajectory_point_step: 4
        threshold_to_consider: 0.5
        offset_from_furthest: 20
        use_path_orientations: false
      PathFollowCritic:
        enabled: true
        cost_power: 1
        cost_weight: 5.0
        offset_from_furthest: 5
        threshold_to_consider: 1.4
      PathAngleCritic:
        enabled: true
        cost_power: 1
        cost_weight: 2.0
        offset_from_furthest: 4
        threshold_to_consider: 0.5
        max_angle_to_furthest: 1.0
        mode: 0
      # TwirlingCritic:
      #   enabled: true
      #   twirling_cost_power: 1
      #   twirling_cost_weight: 10.0

local_costmap:
  local_costmap:
    ros__parameters:
      update_frequency: 5.0
      publish_frequency: 2.0
      global_frame: map
      robot_base_frame: base_footprint
      rolling_window: true
      width: 25 #3
      height: 60  #3
      resolution: 0.05
      robot_radius: 0.9 #0.22
      plugins: ["voxel_layer", "inflation_layer"]
      inflation_layer:
        plugin: "nav2_costmap_2d::InflationLayer"
        cost_scaling_factor: 7.5 #3.0
        inflation_radius: 1.3 #0.70
      voxel_layer:
        plugin: "nav2_costmap_2d::VoxelLayer"
        enabled: True
        publish_voxel_map: True
        origin_z: 1.0
        z_resolution: 0.05
        z_voxels: 160
        max_obstacle_height: 3.0
        mark_threshold: 0
        observation_sources: scan
        scan:
          # A relative topic will be appended to the parent of the local_costmap namespace.
          # For example:
          #   * User chosen namespace is `tb4`.
          #   * User chosen topic is `scan`.
          #   * Topic will be remapped to `/tb4/scan` without `local_costmap`.
          #   * Use global topic `/scan` if you do not wish the node namespace to apply
          topic: /scan
          max_obstacle_height: 3.0
          clearing: True
          marking: True
          data_type: "LaserScan"
          raytrace_max_range: 50.0
          raytrace_min_range: 0.0
          obstacle_max_range: 50.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_footprint
      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:
          # A relative topic will be appended to the parent of the global_costmap namespace.
          # For example:
          #   * User chosen namespace is `tb4`.
          #   * User chosen topic is `scan`.
          #   * Topic will be remapped to `/tb4/scan` without `global_costmap`.
          #   * Use global topic `/scan` if you do not wish the node namespace to apply
          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.7
      always_send_full_costmap: True

# The yaml_filename does not need to be specified since it going to be set by defaults in launch.
# If you'd rather set it in the yaml, remove the default "map" value in the tb3_simulation_launch.py
# file & provide full path to map below. If CLI map configuration or launch default is provided, that will be used.
map_server:
  ros__parameters:
    yaml_filename: ""

map_saver:
  ros__parameters:
    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
    planner_plugins: ["GridBased"]
    costmap_update_timeout: 1.0
    GridBased:
      plugin: "nav2_navfn_planner/NavfnPlanner"
      tolerance: 1.0   #0.5
      use_astar: false
      allow_unknown: true

smoother_server:
  ros__parameters:
    smoother_plugins: ["simple_smoother"]
    simple_smoother:
      plugin: "nav2_smoother::SimpleSmoother"
      tolerance: 1.0e-10
      max_its: 1000
      do_refinement: True

behavior_server:
  ros__parameters:
    local_costmap_topic: local_costmap/costmap_raw
    global_costmap_topic: global_costmap/costmap_raw
    local_footprint_topic: local_costmap/published_footprint
    global_footprint_topic: global_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"
    local_frame: odom_demo
    global_frame: odom_demo #map
    robot_base_frame: base_link
    transform_tolerance: 0.1
    simulate_ahead_time: 2.0
    max_rotational_vel: 1.0
    min_rotational_vel: 0.4
    rotational_acc_lim: 3.2

waypoint_follower:
  ros__parameters:
    loop_rate: 20
    stop_on_failure: false
    action_server_result_timeout: 900.0
    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:
    smoothing_frequency: 20.0
    scale_velocities: False
    feedback: "OPEN_LOOP"
    max_velocity: [0.5, 0.0, 2.0]
    min_velocity: [-0.5, 0.0, -2.0]
    max_accel: [2.5, 0.0, 3.2]
    max_decel: [-2.5, 0.0, -3.2]
    odom_topic: "/car_nav2/odom_demo"
    odom_duration: 0.1
    deadband_velocity: [0.0, 0.0, 0.0]
    velocity_timeout: 1.0

collision_monitor:
  ros__parameters:
    base_frame_id: "base_footprint"
    odom_frame_id: "odom_demo"
    cmd_vel_in_topic: "cmd_vel_smoothed"
    cmd_vel_out_topic: "/car_nav2/cmd_demo" #"cmd_vel"
    state_topic: "collision_monitor_state"
    transform_tolerance: 0.2
    source_timeout: 1.0
    base_shift_correction: True
    stop_pub_timeout: 2.0
    # Polygons represent zone around the robot for "stop", "slowdown" and "limit" action types,
    # and robot footprint for "approach" action type.
    polygons: ["FootprintApproach"]
    FootprintApproach:
      type: "polygon"
      action_type: "approach"
      footprint_topic: "local_costmap/published_footprint"
      time_before_collision: 1.2
      simulation_time_step: 0.1
      min_points: 6
      visualize: False
      enabled: True
    observation_sources: ["scan"]
    scan:
      type: "scan"
      topic: "scan"
      min_height: 0.15
      max_height: 2.0
      enabled: True

docking_server:
  ros__parameters:
    controller_frequency: 50.0
    initial_perception_timeout: 5.0
    wait_charge_timeout: 5.0
    dock_approach_timeout: 30.0
    undock_linear_tolerance: 0.05
    undock_angular_tolerance: 0.1
    max_retries: 3
    base_frame: "base_link"
    fixed_frame: "odom_demo"
    dock_backwards: false
    dock_prestaging_tolerance: 0.5

    # Types of docks
    dock_plugins: ['simple_charging_dock']
    simple_charging_dock:
      plugin: 'opennav_docking::SimpleChargingDock'
      docking_threshold: 0.05
      staging_x_offset: -0.7
      use_external_detection_pose: true
      use_battery_status: false # true
      use_stall_detection: false # true

      external_detection_timeout: 1.0
      external_detection_translation_x: -0.18
      external_detection_translation_y: 0.0
      external_detection_rotation_roll: -1.57
      external_detection_rotation_pitch: -1.57
      external_detection_rotation_yaw: 0.0
      filter_coef: 0.1

    # Dock instances
    # The following example illustrates configuring dock instances.
    # docks: ['home_dock']  # Input your docks here
    # home_dock:
    #   type: 'simple_charging_dock'
    #   frame: map
    #   pose: [0.0, 0.0, 0.0]

    controller:
      k_phi: 3.0
      k_delta: 2.0
      v_linear_min: 0.15
      v_linear_max: 0.15
      use_collision_detection: true
      costmap_topic: "/local_costmap/costmap_raw"
      footprint_topic: "/local_costmap/published_footprint"
      transform_tolerance: 0.1
      projection_time: 5.0
      simulation_step: 0.1
      dock_collision_threshold: 0.3

loopback_simulator:
  ros__parameters:
    base_frame_id: "base_footprint"
    odom_frame_id: "odom_demo"
    map_frame_id: "map"
    scan_frame_id: "laser_link"  # "base_scan"  # tb4_loopback_simulator.launch.py remaps to 'rplidar_link'
    update_duration: 0.02

猜你喜欢

转载自blog.csdn.net/weixin_42899627/article/details/144679673
今日推荐