#!/usr/bin/env python3 """ 步骤3:Nav2 导航 功能:启动 Gazebo + AMCL + Nav2 + RViz2 用途:使用保存的地图进行自主导航 配置:使用 Task_1 的 Nav2 配置(已验证有效) """ import os from launch import LaunchDescription from launch.actions import IncludeLaunchDescription, DeclareLaunchArgument from launch.launch_description_sources import PythonLaunchDescriptionSource from launch.substitutions import LaunchConfiguration, PathJoinSubstitution, Command from launch_ros.actions import Node from launch_ros.substitutions import FindPackageShare from ament_index_python.packages import get_package_share_directory def generate_launch_description(): # 包名和路径 pkg_name = 'final_navigation' pkg_share = FindPackageShare(pkg_name).find(pkg_name) # 文件路径 xacro_file = os.path.join(pkg_share, 'urdf', 'fusion_robot.urdf.xacro') world_file = os.path.join(pkg_share, 'worlds', 'simple_house.world') nav2_params_file = os.path.join(pkg_share, 'config', 'nav2_params.yaml') # 地图文件路径(默认查找顺序) # 1. 检查 install 目录 map_file_install = os.path.join(pkg_share, 'maps', 'my_map.yaml') # 2. 检查工作空间根目录 map_file_ws = os.path.expanduser('~/test/task_final/final_navigation/maps/my_map.yaml') # 选择存在的地图文件 if os.path.exists(map_file_install): map_file = map_file_install print(f"\n✅ 找到地图: {map_file_install}\n") elif os.path.exists(map_file_ws): map_file = map_file_ws print(f"\n✅ 找到地图: {map_file_ws}\n") else: map_file = map_file_install # 使用默认路径 print(f"\n⚠️ 警告: 地图文件不存在!") print(f" 已检查: {map_file_install}") print(f" 已检查: {map_file_ws}") print(f" 请确保已运行 step2_mapping.launch.py 并保存地图\n") rviz_config = os.path.join(pkg_share, 'rviz', 'nav_view.rviz') # Launch 参数 use_sim_time = LaunchConfiguration('use_sim_time', default='true') map_yaml_file = LaunchConfiguration('map', default=map_file) # 处理 xacro 文件 robot_description = Command(['xacro ', xacro_file]) # ======================================== # 1. Gazebo 仿真 # ======================================== gazebo = IncludeLaunchDescription( PythonLaunchDescriptionSource([ PathJoinSubstitution([ FindPackageShare('gazebo_ros'), 'launch', 'gazebo.launch.py' ]) ]), launch_arguments={ 'world': world_file, 'verbose': 'false' }.items() ) # ======================================== # 2. 机器人状态发布器 # ======================================== robot_state_publisher = Node( package='robot_state_publisher', executable='robot_state_publisher', name='robot_state_publisher', output='screen', parameters=[{ 'robot_description': robot_description, 'use_sim_time': use_sim_time }] ) # ======================================== # 3. 在 Gazebo 中生成机器人 # ======================================== spawn_entity = Node( package='gazebo_ros', executable='spawn_entity.py', arguments=[ '-entity', 'fusion_robot', '-topic', 'robot_description', '-x', '0.0', '-y', '0.0', '-z', '0.1' ], output='screen' ) # ======================================== # 4. 地图服务器(使用 Nav2 Bringup 的 localization_launch.py) # ======================================== # 注意:不单独启动 map_server 和 amcl,使用 Nav2 的 localization_launch.py localization = IncludeLaunchDescription( PythonLaunchDescriptionSource([ PathJoinSubstitution([ FindPackageShare('nav2_bringup'), 'launch', 'localization_launch.py' ]) ]), launch_arguments={ 'map': map_yaml_file, 'use_sim_time': 'true', 'params_file': nav2_params_file }.items() ) # ======================================== # 5. Nav2 导航栈 # ======================================== navigation = IncludeLaunchDescription( PythonLaunchDescriptionSource([ PathJoinSubstitution([ FindPackageShare('nav2_bringup'), 'launch', 'navigation_launch.py' ]) ]), launch_arguments={ 'use_sim_time': 'true', 'params_file': nav2_params_file }.items() ) # ======================================== # 6. RViz2 可视化 # ======================================== rviz2 = Node( package='rviz2', executable='rviz2', name='rviz2', arguments=['-d', rviz_config], parameters=[{'use_sim_time': use_sim_time}], output='screen' ) return LaunchDescription([ DeclareLaunchArgument( 'use_sim_time', default_value='true', description='Use simulation time' ), DeclareLaunchArgument( 'map', default_value=map_file, description='Full path to map yaml file' ), gazebo, robot_state_publisher, spawn_entity, localization, navigation, rviz2, ])